1. Introduction to two heap Data Structures

2. Storage Model

3. ImplementationCodeAnalysis

4. Download references and code

** ****<1>. Introduction to heap Data Structure**
** **** **

A two-item heap consists of a group of two trees. Before defining a two-item heap, we first define what a two-item tree is.

The binary tree is a recursive definition:

1. Tree B [0] contains only one node

B [k] is composed of two B [k-1] Two Trees, one of which is the child of another tree.

The following is the binary tree B0-B4:

Obviously, the two trees have the following properties:

1. For Tree B [K], the tree contains 2 ^ K nodes;

2. The height of the tree is K;

3. If the depth is I, it contains the CIK node, where I = 0, 1, 2..., K;

After defining the two-item tree, we will define the two-item heap H below. The two-item heap is composed of a group of two trees that meet the following requirements:

Every two trees in 1. h follow the minimum heap nature;

2. For any integer k, there is no second tree in H where another degree is K;

Other definitions:

1. The level of the two items heap is defined as the number of children;

2. Define the root table of the two items heap as a linked list formed by the root node of the two items tree;

Okay. After the definition of the two items heap is complete, the following question is: under what circumstances should we use the two items heap "?

If Union operations are not supported, the data structure of a normal heap is an ideal data structure. However, if you want to support merge operations on a set, it is best to use two heaps or a Fibonacci heap. The worst case for a normal heap in a union operation is O (n ), but the two heap and the Fibonacci heap are O (lgn ).

** ****<2>. Storage Model**
** **** **

After learning about the definition and application scenarios of the two items heap, let's take a look at how to store the two items heap?

First, define the type of each node in the two items heap:

1. Parent: pointing to the parent node

2. Sibling: pointing to the right brother Node

3. Child: defines the subnode of the node.

4. Degree: defines the degree of the node.

5. data required in other application scenarios

Struct heap_node { Struct heap_node * Parent; Struct heap_node * Next; Struct heap_node * Child; Unsigned int Degree; Void * Value; Struct heap_node ** Ref;

};

For defined fields, the nodes in the root table are different from those in the root table. All the nodes in the root table are empty, and sibling points to the next element in the root table; if a node is not in the root table, parent points to the parent node of the node, and sibling points to the sibling node of the node.

Define two types of heap data:

1. header nodes in the root table

2. data required by other applications

Struct heap { Struct heap_node * Head; Struct heap_node * Min;

};

** ****<3>.AlgorithmAnalysis**
** **** **

3.1 initialize two items heap

Only point the header node of the root table to NULL:

Static inline void heap_init (struct heap * heap ){ Heap-> head = NULL; Heap-> min = NULL; // Other operations

}

3.2 search for the minimum keyword

Because every two-item tree in the Two-item heap follows the minimum heap nature, the minimum element must be in the root table. You can traverse the root table once to find the minimum element:

// Return the smallest element in the two items heap through node, and // return the first node of the smallest element node through the prev pointer // the pointer static inline void _ heap_min (heap_prio_t higher_prio, struct heap * heap, Struct heap_node ** Prev, struct heap_node ** node ){ Struct heap_node * _ Prev, * cur; * Prev = NULL; // if the two items heap is empty If (! Heap-> head ){ * Node = NULL; Return; } * Node = heap-> head; // Save the minimum element node pointer. The default value is "head ". _ Prev = heap-> head; // pointer of the previous Node Cur = heap-> head-> next; While (cur ){ If (higher_prio (cur, * node )){ // Find a smaller Node * Node = cur; * Prev = _ Prev; } _ Prev = cur; Cur = cur-> next; } 3.3 merge operations

Merging two items is a complicated process. Here we assume that the two items to be merged are H1 and H2, if you simply merge the root tables of H1 and H2 (two linked lists), it may be a violation of the second definition of the two heaps:

B [k] is composed of two B [k-1] Two Trees, one of which is the child of another tree.

This is the main problem to be solved for the two heap merge operations: after the two heap merge operations are completed, two nodes with the same degree may exist in the root table, you need to combine nodes with the same degree into a new node.

Here we further convert this problem into: the degree of each node in the root table of H1 and H2 is known, and the root tables of H1 and H2 are sorted by degree, how to merge H1 and H2 root tables, and the new root table does not have two nodes with the same degree.

A simple idea is to merge H1 and H2, and then adjust the nodes with the same degree of degree to merge them, this ensures that the new root table does not store nodes with the same degree. Then the basicProgramFramework:

Union (H1, H2)

{

#1: Merge the root tables of H1 and H2, generate a new root table h, and the nodes of H are sorted by degree;

#2: merge two nodes with the same moderate number in h until there are no nodes with the same degree in the root table h;

}

Continuing to refine the above ideas, #1 is relatively simple, similar to the merging idea in Merge Sorting, but for #2, because h is sorted, we only need to traverse H. If there are two identical degrees, merge them.

// Merge two heap static inline void _ heap_union (heap_prio_t higher_prio, struct heap * heap, Struct heap_node * H2 ){ Struct heap_node * H1; Struct heap_node * Prev, * X, * next; If (! H2) Return; H1 = heap-> head; If (! H1 ){ Heap-> head = h2; Return; } // Merge two root tables H1 = _ heap_merge (H1, H2 ); Prev = NULL; X = h1; Next = x-> next; // Merge nodes with the same degree in the newly merged root table While (next ){ // Case 1 and Case 2 If (X-> degree! = Next-> degree | (Next-> next & next-> degree = x-> degree )){ /* Nothing to do, advance */ Prev = X; X = next; } Else if (higher_prio (x, next )){ // Case 3 /* X becomes the root of next */ X-> next = Next-> next; _ Heap_link (x, next ); } Else { // Case 4 /* Next becomes the root of x */ If (prev) Prev-> next = next; Else H1 = next; _ Heap_link (next, X ); X = next; } Next = x-> next; } Heap-> head = h1;

}

_ Heap_link is an auxiliary function. The function is as follows:

/* Make child a subtree of root to make the child node pointed to by the Child parameter become the child node of the root node */static inline void _ heap_link (struct heap_node * root, Struct heap_node * Child ){ Child-> parent = root; Child-> next = root-> child; Root-> child = child; Root-> degree ++;

}

3.4 extract the smallest keyword Node

Binomial - Heap - Extract - Min (h)

Find the root X with the minimum key In The root list of H,

And remove X from the root list of H

H ' Make-binomial-heap ()

Reverse the order of the linked list of X ' S children,

And Set Head [H ' ] To point to the head of the resulting list

H binomial - Heap - Union (H, H ' )

Return X

// Extract the smallest keyword static inline struct heap_node * _ heap_extract_min (heap_prio_t higher_prio, Struct heap * heap ){ Struct heap_node * Prev, * node; // Find the smallest node, which is stored in the node, and the prev variable stores // The previous node of the node _ Heap_min (higher_prio, heap, & Prev, & node ); If (! Node) // if the root table is empty Return NULL; /* If Prev is not empty, that is, the minimum element is not the first element of the root table */ If (prev) Prev-> next = node-> next; // remove the node from the root table /* If the node (minimum element value) is the first element in the root table, the head pointer of the two items heap will be modified directly. */ Else Heap-> head = node-> next;/* Call _ heap_reverse to reverse output the subnode of the node and merge it with heap */ _ Heap_union (higher_prio, heap, _ heap_reverse (node-> child )); // Return the minimum Node Return node;

}

3.4 reduce the keyword Value

This algorithm is similar to the heap algorithm. If the value of a node is reduced, it may violate the minimum heap nature. Then, it moves up along the parent node and modifies the value of the node.

Binomial-Heap-Decrease-Key (H, X, K)

If K > Key [x]

Then Error " New Key is greater than current key "

Key [x] = K

Y = X

Z = P [y]

While Z ! = Nil and key [y] < Key [Z]

Do Exchange key [y] Key [Z]

// If Y and Z have satellite fields, exchange them, too.

Y = Z

Z = P [y]

// Reduce the keyword value static inline void heap_decrease (heap_prio_t higher_prio, struct heap * heap, Struct heap_node * node ){ Struct heap_node * parent; Struct heap_node ** tmp_ref; Void * TMP; /* Node's priority was decreased, We need to update its position */ If (! Node-> ref) Return; If (heap-> Min! = Node ){ /* The bubble up starts to exchange data with the parent node until it meets the minimum heap nature */ Parent = node-> parent; While (parent & higher_prio (node, parent )){ /* Swap parent and node */ TMP = parent-> value; Parent-> value = node-> value; Node-> value = TMP; /* Swap references */ If (parent-> ref) * (Parent-> ref) = node; * (Node-> ref) = parent; Tmp_ref = parent-> ref; Parent-> ref = node-> ref; Node-> ref = tmp_ref; /* Step up */ Node = parent; Parent = node-> parent; } } 3.5 delete a node

The algorithm used here is relatively simple. First, reduce the keyword value of the node to be deleted, and then call the FunctionBinomial-Heap-Extract-MinDelete the node from the two items heap. The pseudo code of the algorithm is as follows:

Binomial - Heap - Delete (H, X)

Binomial - Heap - Decrease - Key (H, X, - )

Binomial-Heap-Extract-Min (h)

** ****<4>. Download reference materials and code**

Introduction to algorithms: http://net.pku.edu.cn /~ Course/cs101/2007/resource/intro2algorithm/book6/chapturehtm

download code:/files/xuqiang/algorithm/binomialheapusingc.rar