1
Laboratory Module 2
Binomial Heaps and Fibonacci Heaps
Purpose: − understand the properties of binomial and Fibonacci heaps
− to build, in C, a binomial heap
1 Binomial Heaps
In general, a heap is an array data structure in which each key is guaranteed to be larger than the keys
at two other specific positions. In turn, each of those keys must be larger than two more keys, and so forth.
This ordering is very easy to see if we draw the array in a two-dimensional “tree” structure with lines down
from each key to the two keys known to be smaller.
Figure 1. Sample heap viewed as binary tree and as array
An array is a heap if for all values the heap properties hold:
A[i] ≤ A[2*i]
A[i] ≤ A[2*i +1]
From the tree point of view, holding the heap condition becomes: the key in each node should be larger
than (or equal to) the keys in its sons (if it has any). Note that this implies in particular that the largest key
is in the root.
Binomial heaps are an extension or a generalization of the classical heap structure. The generalization
regards the fact that a binomial heap is a collection of binomial trees and a binomial tree is a multiway
heap.
1.1 Binomial Trees A binomial tree Bk is an ordered tree defined recursively. The binomial tree of order zero, B0,consists
of a single node. The binomial tree of order one, B1, consists of a two nodes and is composed of two B0
trees linked together. The binomial tree of order two, B2, consists of four nodes and is composed of two B1
trees linked together. Thus, the binomial tree of order k, Bk, consists of 2k nodes and is composed of two
binomial trees Bk-1 that are linked together. The linking is performed with the following rule: the root of
one is the leftmost child of the root of the other. Next figure shows the binomial trees B0 through B4 and
also the general structure of a Bk binomial tree.
First figure presents the general structure of a binomial tree of order k, Bk, as a combination of two
binomial trees of order k-1, Bk-1. The second figure presents also the structure of a structure of a binomial
tree of order k, Bk with the root node and corresponding k children: B0, B1, …Bk-1. In this representation,
the root and the trees B0, B1, Bk-2 represent one Bk-1 tree from the overall Bk tree.
The third and the forth pictures present the detailed structure of binomial trees of order 0, 1, 2, 3 and 4.
2
a)
b)
c)
d)
Figure 2. Sample Binomial Trees
The properties of the binomial tree of order k, Bk are,
1. The Bk tree has 2k nodes.
2. The height of the Bk tree is k.
3. In a Bk tree, at depth i there are exactly D(k, i) = D(k-1, i) + D(k-1,i-1) nodes. It is known that
D(0,0) = 1, D(1,0) = D(1,1) =1, D(2,0) = D(2,2) = 1.
Example: D(3, 2) = D(2,2) + D(2,1) = 1 + D(1,1) + D(1,0) = 1+1+1 = 3.
4. The root has degree k, which is greater than that of any other node; moreover if i the children of the
root are numbered from left to right by k - 1, k - 2, ..., 0, child i is the root of a subtree Bi.
The structure of a node from a binomial tree is:
typedef struct BinomialNode {
int inf,rank;
BinomialNode *llink,*rlink,*down;
}*pBinomialNode;
The meaning of the fields from the structure of node is:
3
inf – contains the key of the node. The integer values stored in the tree respect the heap property.
rank – represents the degree of the node of the binomial tree. For example, in a B3 tree the rank value
of the root is 3.
llink, rlink, down – contain pointers (addresses) to other nodes. down pointer holds the address of the
direct child of a node. llink and rlink pointers are used to manage a double linked list of nodes which are
children of a certain parent node. There is just only one physical connection between the parent node and
only one of the children and that is represented by the down pointer.
The next figure presents the physical structure of binomial trees.
Figure 3. Physical structure of binomial trees
1.2 Representation of Binomial Heaps
A binomial heap H is a set of binomial trees that satisfies the following properties.
1. Each binomial tree in H obeys the general heap property. It means that for each node of the tree
the following rule is valid: the value of the key is smaller or equal than the values from all of its children.
2. Within the binomial heap there is at most one binomial tree of degree k. Intuitively, there
cannot be two binomial trees of order k within the same heap because they may be merged into a binomial
tree of order k+1. Thus, n keys may be placed in at most ⌊⌊⌊⌊lg(n)⌋⌋⌋⌋ + 1 binomial trees that make up a correctly
build binomial heap.
The second property leads to the binary representation of binomial heaps. The binary representation of
integer n is:
n10 = bi bi-1 …b1 b0, where i = ⌊ lg(n)⌋.
From the binomial heap structural point of view, n keys may be placed in a set of binomial trees where
the maximum degree is i = ⌊ lg(n)⌋. Within the set of binomial trees, binomial tree Bi appears in H if and
only if bit bi = 1.
The structure of a binomial heap may be:
typedef struct BinomialHeap{
int indMin,rank;
pBinomialNode refVectHeap[MAX_ARB];
}*pBinomialHeap;
The meaning of the fields from the structure of node is:
indMin – The position in the refVectHeap vector where there may be found the address of the root
node with the smallest key from all keys of the roots. The key from this node is the smallest key among all
keys from the binomial heap.
rank – the greatest degree of all binomial trees.
refVectHeap – the vector of pointers that hold the addresses for all the roots of the binomial trees that
make up the binomial heap. A NULL in a field from this vector means that the corresponding binomial tree
misses.
4
Next figure shows shows a binomial heap H with 13 nodes. The binary representation of 13 is 1101,
and H consists of binomial trees B3, B2, and B0, having 8, 4, and 1 nodes respectively, for a total of 13
nodes.
Figure 4. Physical structure of binomial heap H13=<B3, B2, -, B0>
As shown above figure, each binomial tree within a binomial heap is stored according with the
representation used in previous section. Each field of the refVectHeap array holds the address of a binomial
tree root if exists. Thus, the roots of the binomial trees within a binomial heap are stored in an array which
is referred to as refVectHeap. The degrees of the roots strictly increase as we traverse the array. Thus, in
position zero of the array we may find only the address of a binomial tree of degree 0. If such a tree does
not exist, a NULL is placed in position zero of the array.
1.3 Operations on Binomial Heaps
1.3.1 Creating a New Binomial Heap
To make an empty binomial heap, the MakeBinomialHeap procedure simply allocates and returns an
structure H, where indMin[H ] = 0, rank[H] = 0 and the refVectHeap is filled with NULL pointers. The
running time is O(1).
1.3.2 Finding the Minimum Key The procedure BINOMIAL-HEAP-MINIMUM returns a pointer to the node with the minimum key in
an n-node binomial heap H.
Since the binomial heap is min-heap-ordered, the minimum key must reside in a root node in position
indMin. If the binomial heap structure does not store such information, regarding the position of the
minimum index than all the roots must be checked. Such a procedure would take O(⌊lg n⌋ + 1) time and the
pseudocode for the algorithm is:
procedure BinomialHeapMinimum(Heap H){
y ← NIL;
x ← head[H];
min ← ∞;
while ( x ≠ NIL ) do{
if ( key[x] < min ){
min ← key[x];
}
5
y ← x;
x ← llink[x];
}
return y;
}
1.3.3 Uniting Two Binomial Heaps
The operation of uniting two binomial heaps is used as a subroutine by most of the remaining
operations. The BINOMIAL-HEAP-UNION procedure repeatedly links binomial trees whose roots have
the same degree. The following procedure links the Bk-1 tree rooted at node y to the Bk-1 tree rooted at node
z; that is, it makes z the parent of y. Node z thus becomes the root of the newly build Bk tree. This
procedure assumes that the key from the node z is smaller or equal than the key from y.
procedure BinomialLink(BinomialTree y, BinomialTree z){
z[down] ← y; // y becomes the child of z
#put y in the doubly linked list of children of z
degree[z] ← degree[z] + 1; //increase the degree of the new obtained binomial tree
}
The BinomialLink procedure makes node y the new head of the linked list of node z's children in
O(1) time. It works because the used representation of each binomial tree matches the ordering property of
the tree: in a Bk tree, the leftmost child of the root is the root of a Bk-1 tree.
The following procedure unites binomial heaps H1 and H2, returning the resulting heap. It alters the
representations of H1 and H2 in the process. Besides BinomialLink, the procedure uses an auxiliary
procedure BinomialHeapMerge that merges the root lists of H1 and H2 into a single array that is sorted by
degree into monotonically increasing order. The BinomialHeapMerge procedure, whose pseudocode we
leave as Exercise 19.2-1, is similar to the MERGE procedure in Section 2.3.1.
procedure BinomialHeapUnion (BinomialHeap H1, BinomialHeap H2) returns Binomial Heap H{
for each binomial tree in H1
for each binomial tree in H2
if (the rank of the binomial tree from H1 is equal with the rank of binomial tree from H2)
#link the binomial trees and place it in correct position in resulting binomial heap
}
This procedure has an O(n*m) complexity time, where n is the rank of H1 and m is the rank of H2.
This approach just wants to point out the main idea of the union procedure which merges any binomial
trees that have the same order.
A much better approach of the same idea is to place the roots of both binomial heaps in the same array
in an increasing order of the ranks and thereafter to proceed with the linking process. This procedure has
O(n+m) time complexity, where n is the rank of H1 and m is the rank of H2.
Here is an example of performing the union procedure. The next figure presents the input binomial
heaps that are merged together.
6
Figure 5. Merging binomial heaps-input data
Step 1. B0 tree from H1 is linked with B0 tree from H2. The result of this linking is a B1 tree.
Step 2. B1 tree from H1 is linked with B1 tree from H2. The result of this linking is a B2 tree.
Step 3. B2 tree from H1 is linked with B2 tree from H2. The result of this linking is a B3 tree.
Result. The resulting heap obtained by union of the initial binomial heaps H1 and H2 is:
7
1.3.4 Inserting a Node in a Binomial Heap
The following procedure inserts node x into binomial heap H, assuming that x has already been
allocated and key[x] has already been filled in.
procedure BinomialHeapInsert (BinomialHeap H, BinomialTreeNode x){
H′ ← MakeBinomialHeap();
p[x] ← NIL;
child[x] ← NIL;
llink[x] = rlink[x] ← NIL;
degree[x] ← 0;
head[H′] ← x;
H ← BinomialHeapUnion (H, H′);
}
The procedure simply makes a one-node binomial heap H′ in O(1) time and unites it with the n-node
binomial heap H in O(lg n) time. The call to BinomialHeapUnion takes care of freeing the temporary
binomial heap H′.
1.3.5 Extracting the Node with Minimum Key
The following procedure extracts the node with the minimum key from binomial heap H and returns a
pointer to the extracted node.
procedure BinomialHeapExtractMin(BinomialHeap 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′ ← MakeBinomialHep();
# place the children of x in H’
H ← BinomialHeapUnion (H, H′);
return x;
}
The next figure presents how works the procedure of extracting the node with the minimum key. In the
initial binomial heap the minimum element is 1, the root of the B4 binomial tree. The goal of the procedure
is to obtain a return the address of the binomial tree node containing key 1 and to obtain a correctly formed
binomial heap where key 1 may not be found anymore.
Step1. The root node x containing the minimum key is obtained and returned. If the binomial heap
structure keeps track of the index where the minimum element resides the x node is obtained in O(1) time.
If such information is not available, all the roots of the binomial trees belonging to binomial heap H must
be inspected.
8
Step 2. Node x is removed from the binomial heap H.
Step 3. All the children of the binomial tree node x are placed in the binomial heap H’.
Step 4. The current binomial heap H is merged with the binomial heap H’. Thus, it is obtained the new
binomial heap H which does not contain key 1.
Figure 5. Deletion of the minimum element from a binomial heap
1.3.6 Decreasing a Key The following procedure decreases the key of a node x in a binomial heap H to a new value k. It
signals an error if k is greater than x's current key.
procedure BinomialHeapDecreaseKey(BinomialHeap H, BinomialNode x, integer k){
if ( k > key[x] )
error "new key is greater than current key"
key[x] ← k;
y ← x
z ← parent[y]
while ( z ≠ NIL and key[y] < key[z] ) do
exchange key[y] ↔ key[z]
}
9
The procedure decreases a key in the same manner as in general heap, by "bubbling up" the key. After
ensuring that the new key is in fact no greater than the current key and then assigning the new key to x, the
procedure goes up the tree, with y initially pointing to node x. In each iteration of the while loop key[y] is
checked against the key of y's parent z. If y is the root or key[y] ≥ key[z], the binomial tree is now correctly
ordered. Otherwise, node y violates min-heap ordering, and so its key is exchanged with the key of its
parent z.
Next figures present the decreasing of key.
Step1.
Here is presented in input
binomial heap containing one
binomial tree, B2.
The procedure wants to
decrease the value of key 40 to
the value of 15.
Step 2.
Value 15 is compared with the
value of the key from the
parent. Since the value from
the parent, which is 30, is
greater than 15 it means key
15 needs to be exchanged with
key 30.
Step 2.
Value 15 is compared with the value
of the key from the parent. Since the
value from the parent, which is 10,
is smaller than 15 it means the
bubbling process ends..
1.3.7 Deleting a Key It is easy to delete a node x's key from binomial heap H in O(lg n) time. The following procedure
assumes that no node currently in the binomial heap has a key of -∞.
procedure BinomialHeapDelete(BinomialHeapH, BinomialNode x){
BinomialHeapDecreaseKey (H, x, -∞);
BinomialHeapExtractMin (H);
}
The BinomialHeapDelete procedure makes node x have the unique minimum key in the entire binomial
heap by giving it a key of -∞. It then bubbles this key up to a root by calling BinomialHeapDecreaseKey.
This root is then removed from H by a call of BinomialHeapExtractMin. The BinomialHeapDelete
procedure takes O(lg n) time.
2 Fibonacci Heaps Fibonacci heaps are a different flavor of heap structures. They support the same operations as binomial
heaps and have similar structure due to the similar rules of building the structure.
Fibonacci heaps are especially used in problems where there is a relatively small number of delete and
minimum key extraction operations. For example, there are classical algorithms on graphs, which need
operations on edges (e.g. modify/decrease the weight) and in this situation an O(1) amortized time for such
operations is a big improvement over the O(lg n) worst-case time of binary or binomial heaps.
The main drawback of Fibonacci heaps structure regards the programming complexity which is much
higher than ordinary heaps or binomial heaps. That is why, Fibonacci heaps are predominantly of
theoretical interest due to the complexity of the data structure.
Like a binomial heap, a Fibonacci heap is a collection of trees. Fibonacci heaps, in fact, are loosely
based on binomial heaps. Like binomial heaps, Fibonacci heaps are not designed to give efficient support to
the operation search; operations that refer to a given node therefore require a pointer to that node as part of
10
their input. When using Fibonacci heaps a good approach is to have access also to a pointer to the
application object from each Fibonacci-heap element.
2.1 The Structure of Fibonacci Heaps The main difference regarding the rules of operating Fibonacci heaps regards the “lazy” character of
unions. In binomial heaps there could not exist two binomial trees having the same rank. Regardless of
performed operation, the structure maintained this property by unifying trees with same rank. In the case of
Fibonacci heaps the union operation is performed only if a DecreaseKey or a Delete operation is
performed. The idea is to delay the procedures that maintain the structure until it is necessary and
convenient to be performed. Thus, at some point we may have many trees with the same rank in a
Fibonacci heap. Unlike trees within binomial heaps, which are ordered, trees within Fibonacci heaps are
unordered. Each node contains a pointer to its parent and a pointer to any one of its children. The children
of a node are linked together in a circular, doubly linked list, which is called the child list of a node. Each
child from a child list has pointers that point to node's left and right siblings, respectively. If a node is the
only child, then left and right pointers point to the node itself. Another important difference from binomial
heaps is that the order in which siblings appear in a child list is arbitrary. This is mainly due to the “free”
way in which unions are performed.
The next figure presents a sample Fibonacci heap with five trees. The roots of the trees are placed in a
simply linked list. The first two trees (with keys 10 and 8, respectively) have degree zero. The third tree has
a root with key 15 and degree 3, because it has three children. One is a direct children (node 25 with degree
zero) and two more children with degree 1. The fourth tree from the heap has a root with degree one and
the last tree has a root with degree two.
Figure 6. Sample Fibonacci Heap
2.1.1 Inserting a Node into a Fibonacci Heap A node is represented by a Fibonacci tree with degree zero. Inserting such a node into a heap is
performed into a straight manner. The F0 tree is created and is placed along the roots of the other trees
belonging to the heap near the min position. If the value from the new node is smaller than the value from
the min address than the min is updated to point to the new minimum.
The procedure for inserting an F0 Fibonacci tree into a Fibonacci heap is
procedure FibonacciHeapInsert( FibinacciHeap H, FibonacciTree x){
x ← CreateNewFibonacciTree();
#concatenate x with root list H
if ( (min[H] = NULL) or (key[x] < key[min[H]]) ){
min[H] ← x;
}
n[H] ← n[H] + 1;// increase the number of nodes from the heap
}
11
The procedure CreateNewFibonacciTree() creates a new Fibonacci tree node, sets its rank to zero, and
all its pointers to NULL. For example, adding 6 to the presented sample Fibonacci heap creates the
following structure.
Figure 7. The Fibonacci Heap after Insertion of 6
2.2 Uniting two Fibonacci heaps The following procedure unites Fibonacci heaps H1 and H2, destroying H1 and H2 in the process. The
procedure simply concatenates the root lists of H1 and H2 and then determines the new minimum node. This
procedure does not consolidate any trees.
procedure FibonacciHeapUnion (FibonacciHeap H1, FibonacciHeap H2){
#create new Fibonacci heap H
min[H] ← min[H1];
#concatenate the root list of H2 with the root list of H
if (min[H1] = NIL) or (min[H2] ≠ NIL and min[H2] < min[H1]){
min[H] ← min[H2];
}
n[H] ← n[H1] + n[H2];
#free the objects H1 and H2
return H;
}
2.3 Extracting the Minimum Node The process of extracting the minimum node is the most complicated of the operations on Fibonacci
heaps. It is also where the delayed work of consolidating trees in the root list finally occurs. The following
pseudocode extracts the minimum node. The procedure assumes for convenience that when a node is
removed from a linked list, pointers remaining in the list are updated, but pointers in the extracted node are
left unchanged. It also uses the auxiliary procedure Consolidate, which will be presented shortly.
procedure FibonacciHeapExtractMin (FibonacciHeap H){
z ← min[H];
if (z ≠ NIL){
for each child x of z do{
add x to the root list of H
p[x] ← NIL
}
# remove z from the root list of H
if ( z = right[z] ) {
min[H] ← NIL;
}else{
min[H] ← right[z];
}
Consolidate(H);
12
n[H] ← n[H] – 1;
}
return z;
}
The procedure works by first making a root out of each of the minimum node's children and removing
the minimum node from the root list. It then consolidates the root list by linking roots of equal degree until
at most one root remains of each degree.
The procedure that consolidates the heap is:
procedure Consolidate(FibonacciHeap H){
for i ← 0 to D(n[H]) do{
A[i] ← NIL;
}
for each node w in the root list of H do{
x ← w
d ← degree[x]
while (A[d] ≠ NIL) do{
y ← A[d]; //Another node with the same degree as x.
if ( key[x] > key[y] )
exchange x ↔ y
FibonacciHeapLink(H, y, x);
A[d] ← NIL;
d ← d + 1;
}//end while
A[d] ← x;
}//end for each
min[H] ← NIL;
for i ← 0 to D(n[H]) do{
if ( A[i] ≠ NIL ){
#add A[i] to the root list of H;
if ( min[H] = NIL or key[A[i]] < key[min[H]] )
min[H] ← A[i];
}// end if
}// end for
}
The functionality of FibonacciHeapLink procedure is quite similar with the functionality of
BinomialLink procedure used for binomial heaps.
procedure FibonacciHeapLink (FibonacciHeap H, FibonacciTreeRoot y, FibonacciTreeRoot x){
# remove y from the root list of H
# make y a child of x, incrementing degree[x]
mark[y] ← FALSE;
} Next figures present the steps of extracting the minimum key from a Fibonacci heap.
Input:
This figure presents the input Fibonacci heap with the minimum key of value 1 in grey filling.
13
Step1:
At this step, all the children of root node 1 (trees with roots 19, 18 and 25) are inserted as trees of the
Fibonacci heap. Since none of the newly added tree roots is not smaller than current minimum value, the
minimum of the Fibonacci heap remains the same. The next steps will consolidate the heap by uniting
trees of the same degree in trees of higher degree.
Step 2: Merge 8 and 10,
merge 18 and 19.
Tree with root 8, containing
only one node, is merged
with the tree with root 10,
also containing only one
node. The resulting tree has
root 8 with degree 1.
In the same way, the tree with
root 18, containing two
nodes, is merged with the tree
with root 19, containing two
nodes. The resulting tree has
root 18 with degree 2.
Step 3. Merge 2 and 8, merge
18 and 11.
Tree with root 8, containing
two nodes, is merged with the
tree with root 2, also
containing two nodes. The
resulting tree has root 2 with
degree 2.
In the same way, the tree with
root 18 is merged with the
tree with root 11. The
resulting tree has root 11 with
14
degree 3.
2.4 Decreasing a Key In the following procedure presents the steps needed for decreasing the key from Fibonacci node x to
the value k.
procedure FibonacciHeapDecreaseKey(FinonacciHeap H, FibonacciNode x, value k){
if ( k > key[x] ){
error "new key is greater than current key"
}
key[x] ← k;
y ← parent[x];
if ( y ≠ NIL and key[x] < key[y] ){
Cut(H, x, y)
CascadingCut(H, y)
}
if ( key[x] < key[min[H]] ){
min[H] ← x
}
}
procedure Cut(FinonacciHeap H, FibonacciNode x, FibonacciNode y){
# remove x from the child list of y, decrementing degree[y]
# add x to the root list of H
parent[x] ← NIL;
mark[y] ← TRUE
}
procedure CascadingCut(FinonacciHeap H, FibonacciNode y){
z ← parent[y];
if ( z ≠ NIL ){
if ( mark[y] = FALSE ) {
mark[y] ← TRUE;
}else{
Cut(H, y, z);
CascadingCut(H, z)
}
}// end if
}
Firstly, the procedure must ensure that the new key is no greater than the current key of x and then
assigns the new key to x. If x is a root or if key[x] ≥ key[y], where y is x's parent, then no structural
changes need occur, since minimum heap ordering has not been violated.
If minimum heap ordering has been violated other changes are necessary. Node x is cut from the tree.
The Cut procedure "cuts" the link between x and its parent y and makes x a root node. The CascadingCut
procedure calls itself recursively on y's parent z. The CascadingCut procedure recurses way up the tree
until either a root or an unmarked node is found.
Next figures present the steps of decreasing two keys in a Fibonacci heap.
15
Decrease the value of key 10 to value 3
Initially, the Fibonacci heap has two trees with
roots 25 and 2. The degrees of roots are 0 and 2,
respectively.
Decreasing key 10 to value 3 cuts the node with
key 10, puts value 3 in it and places it as a root
node with degree zero.
Decrease the value of key 8 to value 1
Initially, the Fibonacci heap has three trees with
roots 3, 25 and 2. The degrees of roots are 0, 0
and 2, respectively.
Decreasing key 8 to value 1 cuts the node with
key 8, puts value 1 in it and places it as a root
node with degree zero.
Here is the final shape of the Fibonacci heap.
Observe that the min pointer now contains the
address of root node with key 1.
3 Assignments
1) Compute the number of nodes at level 5 in a B8 tree (binomial tree of degree 8).
2) Suppose that x is a node in a binomial tree within a binomial heap, and assume that llink[x] ≠ NIL.
Can x be a root node?
What is the value of degree[llink[x]] compared to degree[x]?
3) If x is a nonroot node in a binomial tree within a binomial heap, how does degree[x] compare to
degree[parent[x]]?
4) Present the final binomial heap after inserting keys 7, 2, 6, 10, 15, 32, 17. Present the obtained
binomial heap after each insertion.
5) Implement a function that directly inserts a binomial node into a binomial heap without merging two
heaps.
6) Implement graph algorithms such as computing minimum spanning trees and finding single source
shortest paths using Fibonacci heaps.
7) Show the Fibonacci heap that results from calling FibonacciHeapExtractMin on the Fibonacci heap
shown in below figure.
16