Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
FibonacciHeap.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <stdexcept>
9#include <cmath> // maxDegree
10
11namespace alib {
12
13// fibonacci heap used as mergeable priority queue
14template < typename T, typename Comparator = std::less < T > >
16public:
17 FibonacciHeap ( Comparator comparator = Comparator ( ) ) : m_max( nullptr ), m_size( 0 ), m_comparator( comparator ) {
18 }
19
21
22 // inserts a node with new value into the heap
23 void insert ( const T & value );
24
25 // finds the maximum value in the heap
26 const T & getMax ( ) const {
27 return m_max->value;
28 }
29
30 // finds and removes the maximum value from the heap
31 T extractMax ( );
32
33 // merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
35
36 size_t size ( ) const {
37 return m_size;
38 }
39
40// void print ( );
41
42// void checkConsystency ( );
43
44protected:
45 struct Node {
47 unsigned degree;
48 bool mark;
53 Node(const T & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * pr = nullptr, Node * ne = nullptr)
54 : value(val), degree(deg), mark(false), parent(par), child(chld), prev(pr), next(ne) {}
55 };
56
57 Node * m_max; //< pointer to cyclic doubly linked list of trees
58 size_t m_size; //< count of elements stored in the heap
59 Comparator m_comparator; //< user-defined comparator function
60
61protected:
62
63 // deletes one linked list of trees
64 void deleteTreeList( Node * head );
65
66 // connects doubly linked lists from 2 fibonacci heaps and returns address of head of the new linked list
67 void mergeHeaps( Node * & max1, Node * & max2 );
68
69 // goes through list of trees and merges trees with same degree
70 void consolidate();
71
72 // links tree to child list of node
73 void linkTreeToNode( Node * node, Node * tree );
74
75// void printNode ( Node * node );
76
77// void checkConsystency ( Node * node, Node * parent );
78};
79
80
81template < typename T, typename Comparator >
83 deleteTreeList( m_max );
84}
85
86template < typename T, typename Comparator >
88 if ( ! head )
89 return;
90
91 Node * actual = head;
92 do {
93 Node * next = actual->next;
94 deleteTreeList( actual->child );
95 delete actual;
96 actual = next;
97 } while (actual != head);
98}
99
100template < typename T, typename Comparator >
102 Node * newNode = new Node( value, 0, nullptr, nullptr, nullptr, nullptr );
103 newNode->prev = newNode;
104 newNode->next = newNode; // make this node be a single-element cyclic list
105
106 if (!m_max) {
107 m_max = newNode; // this heap is empty, newNode becomes head of a linked list
108 m_size = 1;
109 return;
110 }
111
112 mergeHeaps( m_max, newNode ); // link the newNode into the existing linked list
113
114 m_max = m_comparator ( newNode->value, m_max->value ) ? m_max : newNode;
115
116 m_size++;
117}
118
119template < typename T, typename Comparator >
121 if ( m_max == nullptr )
122 throw std::out_of_range ( "Heap is empty." );
123
124 Node * z = m_max;
125 T maxVal = z->value;
126
127 if (z->child != nullptr) {
128 Node * z1 = z->child;
129 do {
130 z1->parent = nullptr;
131 z1 = z1->next;
132 } while (z1 != z->child);
133 }
134
135 mergeHeaps ( z, z->child );
136
137 if (z == z->next)
138 m_max = nullptr;
139 else {
140 m_max = z->next;
141 m_max->prev = z->prev;
142 z->prev->next = m_max;
143 consolidate();
144 }
145
146 m_size--;
147 delete z;
148 return maxVal;
149}
150
151template < typename T, typename Comparator >
153 if (this->m_comparator != that.m_comparator) // nodes of these heaps are sorted by different condition
154 throw std::logic_error("compare functions aren't equal, unable to merge");
155
156 mergeHeaps( this->m_max, that.m_max ); // link the other heap into this heap
157 this->m_max = m_comparator ( that.m_max->value, m_max->value ) ? this->m_max : that.m_max;
158 that.m_max = nullptr;
159
160 this->m_size += that.m_size;
161 that.m_size = 0;
162}
163
164template < typename T, typename Comparator >
166 if ( ! max1 ) {
167 max1 = max2; // this heap is empty, move the content from the other heap inside
168 } else if ( max2 ) {
169 Node * max2prev = max2->prev;
170
171 max2->prev->next = max1;
172 max2->prev = max1->prev; // this magicaly works even if the lists contain only one node
173 max1->prev->next = max2;
174 max1->prev = max2prev;
175 }
176}
177
178template < typename T, typename Comparator >
180 unsigned maxDegree = log2( m_size );
181 Node * * rootsByDegree = new Node * [ maxDegree + 1 ];
182 for (unsigned i = 0; i <= maxDegree; i++)
183 rootsByDegree[i] = nullptr;
184
185 Node * next = m_max;
186 Node * actual = next;
187
188 bool finish = next == next->next;
189 while ( ! finish ) {
190 actual = next;
191 next = actual->next;
192 finish = next == rootsByDegree [ next->degree ];
193
194 while ( rootsByDegree[ actual->degree ] != nullptr) {
195 Node * other = rootsByDegree[ actual->degree ];
196 rootsByDegree[ actual->degree ] = nullptr;
197
198 if ( m_comparator ( other->value, actual->value ) ) {
199 linkTreeToNode( actual, other );
200 } else {
201 linkTreeToNode( other, actual );
202 actual = other;
203 }
204
205 }
206 rootsByDegree[ actual->degree ] = actual;
207 };
208
209 delete [] rootsByDegree;
210
211 m_max = actual;
212 Node * node = actual;
213 do {
214 if ( m_comparator ( m_max->value, node->value ) )
215 m_max = node;
216 node = node->next;
217 } while ( node != actual );
218}
219
220template < typename T, typename Comparator >
222 tree->prev->next = tree->next;
223 tree->next->prev = tree->prev;
224
225 tree->prev = tree;
226 tree->next = tree;
227
228 tree->parent = node;
229 node->degree ++;
230
231 mergeHeaps ( node->child, tree );
232}
233
234/*template < typename T, typename Comparator >
235void FibonacciHeap< T, Comparator >::print() {
236 if ( m_max == nullptr )
237 std::cout << "Empty" << std::endl;
238
239 printNode ( m_max );
240}
241
242template < typename T, typename Comparator >
243void FibonacciHeap < T >::printNode ( Node * node ) {
244 if ( node == nullptr )
245 return;
246
247 Node * actual = node;
248 do {
249 std::cout << " Value: " << actual->value << " Parent: " << ((actual->parent) ? actual->parent->id : -1) << " Left: " << actual->prev->id << " Right: " << actual->next->id << std::endl;
250 printNode ( actual->child );
251 actual = actual->next;
252
253 } while ( node != actual );
254}
255
256template < typename T, typename Comparator >
257void FibonacciHeap< T, Comparator >::checkConsystency() {
258 checkConsystency ( m_max, nullptr );
259}
260
261template < typename T, typename Comparator >
262void FibonacciHeap < T >::checkConsystency ( Node * node, Node * parent ) {
263 if ( node == nullptr )
264 return;
265
266 Node * actual = node;
267 do {
268 assert ( node == node->prev->next && node->next->prev == node && node->parent == parent );
269 checkConsystency ( actual->child, actual );
270 actual = actual->next;
271
272 } while ( node != actual );
273}*/
274
275} /* namespace alib */
276
Definition: FibonacciHeap.h:15
Comparator m_comparator
Definition: FibonacciHeap.h:59
FibonacciHeap(Comparator comparator=Comparator())
Definition: FibonacciHeap.h:17
void mergeWith(FibonacciHeap< T, Comparator > &&that)
Definition: FibonacciHeap.h:152
void linkTreeToNode(Node *node, Node *tree)
Definition: FibonacciHeap.h:221
void deleteTreeList(Node *head)
Definition: FibonacciHeap.h:87
void mergeHeaps(Node *&max1, Node *&max2)
Definition: FibonacciHeap.h:165
void insert(const T &value)
Definition: FibonacciHeap.h:101
~FibonacciHeap()
Definition: FibonacciHeap.h:82
size_t m_size
Definition: FibonacciHeap.h:58
size_t size() const
Definition: FibonacciHeap.h:36
Node * m_max
Definition: FibonacciHeap.h:57
T extractMax()
Definition: FibonacciHeap.h:120
const T & getMax() const
Definition: FibonacciHeap.h:26
void consolidate()
Definition: FibonacciHeap.h:179
Definition: ExceptionHandler.cpp:13
int i
Definition: AllEpsilonClosure.h:118
Definition: Node.cpp:11
Definition: BackwardOccurrenceTest.h:17
Definition: FibonacciHeap.h:45
Node * parent
Definition: FibonacciHeap.h:49
Node * prev
Definition: FibonacciHeap.h:51
bool mark
Definition: FibonacciHeap.h:48
T value
Definition: FibonacciHeap.h:46
Node * child
Definition: FibonacciHeap.h:50
Node(const T &val, unsigned deg=0, Node *par=nullptr, Node *chld=nullptr, Node *pr=nullptr, Node *ne=nullptr)
Definition: FibonacciHeap.h:53
Node * next
Definition: FibonacciHeap.h:52
unsigned degree
Definition: FibonacciHeap.h:47