fibonacci_heap.h revision 1.3 1 1.3 mrg /* Fibonacci heap for GNU compiler.
2 1.3 mrg Copyright (C) 1998-2017 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Daniel Berlin (dan (at) cgsoftware.com).
4 1.1 mrg Re-implemented in C++ by Martin Liska <mliska (at) suse.cz>
5 1.1 mrg
6 1.1 mrg This file is part of GCC.
7 1.1 mrg
8 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
9 1.1 mrg the terms of the GNU General Public License as published by the Free
10 1.1 mrg Software Foundation; either version 3, or (at your option) any later
11 1.1 mrg version.
12 1.1 mrg
13 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 1.1 mrg for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU General Public License
19 1.1 mrg along with GCC; see the file COPYING3. If not see
20 1.1 mrg <http://www.gnu.org/licenses/>. */
21 1.1 mrg
22 1.1 mrg /* Fibonacci heaps are somewhat complex, but, there's an article in
23 1.1 mrg DDJ that explains them pretty well:
24 1.1 mrg
25 1.1 mrg http://www.ddj.com/articles/1997/9701/9701o/9701o.htm?topic=algoritms
26 1.1 mrg
27 1.1 mrg Introduction to algorithms by Corman and Rivest also goes over them.
28 1.1 mrg
29 1.1 mrg The original paper that introduced them is "Fibonacci heaps and their
30 1.1 mrg uses in improved network optimization algorithms" by Tarjan and
31 1.1 mrg Fredman (JACM 34(3), July 1987).
32 1.1 mrg
33 1.1 mrg Amortized and real worst case time for operations:
34 1.1 mrg
35 1.1 mrg ExtractMin: O(lg n) amortized. O(n) worst case.
36 1.1 mrg DecreaseKey: O(1) amortized. O(lg n) worst case.
37 1.1 mrg Insert: O(1) amortized.
38 1.1 mrg Union: O(1) amortized. */
39 1.1 mrg
40 1.1 mrg #ifndef GCC_FIBONACCI_HEAP_H
41 1.1 mrg #define GCC_FIBONACCI_HEAP_H
42 1.1 mrg
43 1.1 mrg /* Forward definition. */
44 1.1 mrg
45 1.1 mrg template<class K, class V>
46 1.1 mrg class fibonacci_heap;
47 1.1 mrg
48 1.1 mrg /* Fibonacci heap node class. */
49 1.1 mrg
50 1.1 mrg template<class K, class V>
51 1.1 mrg class fibonacci_node
52 1.1 mrg {
53 1.1 mrg typedef fibonacci_node<K,V> fibonacci_node_t;
54 1.1 mrg friend class fibonacci_heap<K,V>;
55 1.1 mrg
56 1.1 mrg public:
57 1.1 mrg /* Default constructor. */
58 1.1 mrg fibonacci_node (): m_parent (NULL), m_child (NULL), m_left (this),
59 1.1 mrg m_right (this), m_degree (0), m_mark (0)
60 1.1 mrg {
61 1.1 mrg }
62 1.1 mrg
63 1.1 mrg /* Constructor for a node with given KEY. */
64 1.3 mrg fibonacci_node (K key, V *data = NULL): m_parent (NULL), m_child (NULL),
65 1.3 mrg m_left (this), m_right (this), m_key (key), m_data (data),
66 1.1 mrg m_degree (0), m_mark (0)
67 1.1 mrg {
68 1.1 mrg }
69 1.1 mrg
70 1.1 mrg /* Compare fibonacci node with OTHER node. */
71 1.1 mrg int compare (fibonacci_node_t *other)
72 1.1 mrg {
73 1.1 mrg if (m_key < other->m_key)
74 1.1 mrg return -1;
75 1.1 mrg if (m_key > other->m_key)
76 1.1 mrg return 1;
77 1.1 mrg return 0;
78 1.1 mrg }
79 1.1 mrg
80 1.1 mrg /* Compare the node with a given KEY. */
81 1.1 mrg int compare_data (K key)
82 1.1 mrg {
83 1.1 mrg return fibonacci_node_t (key).compare (this);
84 1.1 mrg }
85 1.1 mrg
86 1.1 mrg /* Remove fibonacci heap node. */
87 1.1 mrg fibonacci_node_t *remove ();
88 1.1 mrg
89 1.1 mrg /* Link the node with PARENT. */
90 1.1 mrg void link (fibonacci_node_t *parent);
91 1.1 mrg
92 1.1 mrg /* Return key associated with the node. */
93 1.1 mrg K get_key ()
94 1.1 mrg {
95 1.1 mrg return m_key;
96 1.1 mrg }
97 1.1 mrg
98 1.1 mrg /* Return data associated with the node. */
99 1.1 mrg V *get_data ()
100 1.1 mrg {
101 1.1 mrg return m_data;
102 1.1 mrg }
103 1.1 mrg
104 1.1 mrg private:
105 1.1 mrg /* Put node B after this node. */
106 1.1 mrg void insert_after (fibonacci_node_t *b);
107 1.1 mrg
108 1.1 mrg /* Insert fibonacci node B after this node. */
109 1.1 mrg void insert_before (fibonacci_node_t *b)
110 1.1 mrg {
111 1.1 mrg m_left->insert_after (b);
112 1.1 mrg }
113 1.1 mrg
114 1.1 mrg /* Parent node. */
115 1.1 mrg fibonacci_node *m_parent;
116 1.1 mrg /* Child node. */
117 1.1 mrg fibonacci_node *m_child;
118 1.1 mrg /* Left sibling. */
119 1.1 mrg fibonacci_node *m_left;
120 1.1 mrg /* Right node. */
121 1.1 mrg fibonacci_node *m_right;
122 1.1 mrg /* Key associated with node. */
123 1.1 mrg K m_key;
124 1.1 mrg /* Data associated with node. */
125 1.1 mrg V *m_data;
126 1.1 mrg
127 1.1 mrg #if defined (__GNUC__) && (!defined (SIZEOF_INT) || SIZEOF_INT < 4)
128 1.1 mrg /* Degree of the node. */
129 1.1 mrg __extension__ unsigned long int m_degree : 31;
130 1.1 mrg /* Mark of the node. */
131 1.1 mrg __extension__ unsigned long int m_mark : 1;
132 1.1 mrg #else
133 1.1 mrg /* Degree of the node. */
134 1.1 mrg unsigned int m_degree : 31;
135 1.1 mrg /* Mark of the node. */
136 1.1 mrg unsigned int m_mark : 1;
137 1.1 mrg #endif
138 1.1 mrg };
139 1.1 mrg
140 1.1 mrg /* Fibonacci heap class. */
141 1.1 mrg template<class K, class V>
142 1.1 mrg class fibonacci_heap
143 1.1 mrg {
144 1.1 mrg typedef fibonacci_node<K,V> fibonacci_node_t;
145 1.1 mrg friend class fibonacci_node<K,V>;
146 1.1 mrg
147 1.1 mrg public:
148 1.1 mrg /* Default constructor. */
149 1.1 mrg fibonacci_heap (K global_min_key): m_nodes (0), m_min (NULL), m_root (NULL),
150 1.1 mrg m_global_min_key (global_min_key)
151 1.1 mrg {
152 1.1 mrg }
153 1.1 mrg
154 1.1 mrg /* Destructor. */
155 1.1 mrg ~fibonacci_heap ()
156 1.1 mrg {
157 1.1 mrg while (m_min != NULL)
158 1.1 mrg delete (extract_minimum_node ());
159 1.1 mrg }
160 1.1 mrg
161 1.1 mrg /* Insert new node given by KEY and DATA associated with the key. */
162 1.1 mrg fibonacci_node_t *insert (K key, V *data);
163 1.1 mrg
164 1.1 mrg /* Return true if no entry is present. */
165 1.1 mrg bool empty ()
166 1.1 mrg {
167 1.1 mrg return m_nodes == 0;
168 1.1 mrg }
169 1.1 mrg
170 1.1 mrg /* Return the number of nodes. */
171 1.1 mrg size_t nodes ()
172 1.1 mrg {
173 1.1 mrg return m_nodes;
174 1.1 mrg }
175 1.1 mrg
176 1.1 mrg /* Return minimal key presented in the heap. */
177 1.1 mrg K min_key ()
178 1.1 mrg {
179 1.1 mrg if (m_min == NULL)
180 1.1 mrg gcc_unreachable ();
181 1.1 mrg
182 1.1 mrg return m_min->m_key;
183 1.1 mrg }
184 1.1 mrg
185 1.1 mrg /* For given NODE, set new KEY value. */
186 1.1 mrg K replace_key (fibonacci_node_t *node, K key)
187 1.1 mrg {
188 1.1 mrg K okey = node->m_key;
189 1.1 mrg
190 1.1 mrg replace_key_data (node, key, node->m_data);
191 1.1 mrg return okey;
192 1.1 mrg }
193 1.1 mrg
194 1.1 mrg /* For given NODE, decrease value to new KEY. */
195 1.1 mrg K decrease_key (fibonacci_node_t *node, K key)
196 1.1 mrg {
197 1.1 mrg gcc_assert (key <= node->m_key);
198 1.1 mrg return replace_key (node, key);
199 1.1 mrg }
200 1.1 mrg
201 1.1 mrg /* For given NODE, set new KEY and DATA value. */
202 1.1 mrg V *replace_key_data (fibonacci_node_t *node, K key, V *data);
203 1.1 mrg
204 1.1 mrg /* Extract minimum node in the heap. If RELEASE is specified,
205 1.1 mrg memory is released. */
206 1.1 mrg V *extract_min (bool release = true);
207 1.1 mrg
208 1.1 mrg /* Return value associated with minimum node in the heap. */
209 1.1 mrg V *min ()
210 1.1 mrg {
211 1.1 mrg if (m_min == NULL)
212 1.1 mrg return NULL;
213 1.1 mrg
214 1.1 mrg return m_min->m_data;
215 1.1 mrg }
216 1.1 mrg
217 1.1 mrg /* Replace data associated with NODE and replace it with DATA. */
218 1.1 mrg V *replace_data (fibonacci_node_t *node, V *data)
219 1.1 mrg {
220 1.1 mrg return replace_key_data (node, node->m_key, data);
221 1.1 mrg }
222 1.1 mrg
223 1.1 mrg /* Delete NODE in the heap. */
224 1.1 mrg V *delete_node (fibonacci_node_t *node, bool release = true);
225 1.1 mrg
226 1.1 mrg /* Union the heap with HEAPB. */
227 1.1 mrg fibonacci_heap *union_with (fibonacci_heap *heapb);
228 1.1 mrg
229 1.1 mrg private:
230 1.1 mrg /* Insert new NODE given by KEY and DATA associated with the key. */
231 1.1 mrg fibonacci_node_t *insert (fibonacci_node_t *node, K key, V *data);
232 1.1 mrg
233 1.3 mrg /* Insert new NODE that has already filled key and value. */
234 1.3 mrg fibonacci_node_t *insert_node (fibonacci_node_t *node);
235 1.3 mrg
236 1.1 mrg /* Insert it into the root list. */
237 1.1 mrg void insert_root (fibonacci_node_t *node);
238 1.1 mrg
239 1.1 mrg /* Remove NODE from PARENT's child list. */
240 1.1 mrg void cut (fibonacci_node_t *node, fibonacci_node_t *parent);
241 1.1 mrg
242 1.1 mrg /* Process cut of node Y and do it recursivelly. */
243 1.1 mrg void cascading_cut (fibonacci_node_t *y);
244 1.1 mrg
245 1.1 mrg /* Extract minimum node from the heap. */
246 1.1 mrg fibonacci_node_t * extract_minimum_node ();
247 1.1 mrg
248 1.1 mrg /* Remove root NODE from the heap. */
249 1.1 mrg void remove_root (fibonacci_node_t *node);
250 1.1 mrg
251 1.1 mrg /* Consolidate heap. */
252 1.1 mrg void consolidate ();
253 1.1 mrg
254 1.1 mrg /* Number of nodes. */
255 1.1 mrg size_t m_nodes;
256 1.1 mrg /* Minimum node of the heap. */
257 1.1 mrg fibonacci_node_t *m_min;
258 1.1 mrg /* Root node of the heap. */
259 1.1 mrg fibonacci_node_t *m_root;
260 1.1 mrg /* Global minimum given in the heap construction. */
261 1.1 mrg K m_global_min_key;
262 1.1 mrg };
263 1.1 mrg
264 1.1 mrg /* Remove fibonacci heap node. */
265 1.1 mrg
266 1.1 mrg template<class K, class V>
267 1.1 mrg fibonacci_node<K,V> *
268 1.1 mrg fibonacci_node<K,V>::remove ()
269 1.1 mrg {
270 1.1 mrg fibonacci_node<K,V> *ret;
271 1.1 mrg
272 1.1 mrg if (this == m_left)
273 1.1 mrg ret = NULL;
274 1.1 mrg else
275 1.1 mrg ret = m_left;
276 1.1 mrg
277 1.1 mrg if (m_parent != NULL && m_parent->m_child == this)
278 1.1 mrg m_parent->m_child = ret;
279 1.1 mrg
280 1.1 mrg m_right->m_left = m_left;
281 1.1 mrg m_left->m_right = m_right;
282 1.1 mrg
283 1.1 mrg m_parent = NULL;
284 1.1 mrg m_left = this;
285 1.1 mrg m_right = this;
286 1.1 mrg
287 1.1 mrg return ret;
288 1.1 mrg }
289 1.1 mrg
290 1.1 mrg /* Link the node with PARENT. */
291 1.1 mrg
292 1.1 mrg template<class K, class V>
293 1.1 mrg void
294 1.1 mrg fibonacci_node<K,V>::link (fibonacci_node<K,V> *parent)
295 1.1 mrg {
296 1.1 mrg if (parent->m_child == NULL)
297 1.1 mrg parent->m_child = this;
298 1.1 mrg else
299 1.1 mrg parent->m_child->insert_before (this);
300 1.1 mrg m_parent = parent;
301 1.1 mrg parent->m_degree++;
302 1.1 mrg m_mark = 0;
303 1.1 mrg }
304 1.1 mrg
305 1.1 mrg /* Put node B after this node. */
306 1.1 mrg
307 1.1 mrg template<class K, class V>
308 1.1 mrg void
309 1.1 mrg fibonacci_node<K,V>::insert_after (fibonacci_node<K,V> *b)
310 1.1 mrg {
311 1.1 mrg fibonacci_node<K,V> *a = this;
312 1.1 mrg
313 1.1 mrg if (a == a->m_right)
314 1.1 mrg {
315 1.1 mrg a->m_right = b;
316 1.1 mrg a->m_left = b;
317 1.1 mrg b->m_right = a;
318 1.1 mrg b->m_left = a;
319 1.1 mrg }
320 1.1 mrg else
321 1.1 mrg {
322 1.1 mrg b->m_right = a->m_right;
323 1.1 mrg a->m_right->m_left = b;
324 1.1 mrg a->m_right = b;
325 1.1 mrg b->m_left = a;
326 1.1 mrg }
327 1.1 mrg }
328 1.1 mrg
329 1.1 mrg /* Insert new node given by KEY and DATA associated with the key. */
330 1.1 mrg
331 1.1 mrg template<class K, class V>
332 1.1 mrg fibonacci_node<K,V>*
333 1.1 mrg fibonacci_heap<K,V>::insert (K key, V *data)
334 1.1 mrg {
335 1.1 mrg /* Create the new node. */
336 1.3 mrg fibonacci_node<K,V> *node = new fibonacci_node_t (key, data);
337 1.1 mrg
338 1.3 mrg return insert_node (node);
339 1.1 mrg }
340 1.1 mrg
341 1.3 mrg /* Insert new NODE given by DATA associated with the key. */
342 1.1 mrg
343 1.1 mrg template<class K, class V>
344 1.1 mrg fibonacci_node<K,V>*
345 1.1 mrg fibonacci_heap<K,V>::insert (fibonacci_node_t *node, K key, V *data)
346 1.1 mrg {
347 1.1 mrg /* Set the node's data. */
348 1.1 mrg node->m_data = data;
349 1.1 mrg node->m_key = key;
350 1.1 mrg
351 1.3 mrg return insert_node (node);
352 1.3 mrg }
353 1.3 mrg
354 1.3 mrg /* Insert new NODE that has already filled key and value. */
355 1.3 mrg
356 1.3 mrg template<class K, class V>
357 1.3 mrg fibonacci_node<K,V>*
358 1.3 mrg fibonacci_heap<K,V>::insert_node (fibonacci_node_t *node)
359 1.3 mrg {
360 1.1 mrg /* Insert it into the root list. */
361 1.1 mrg insert_root (node);
362 1.1 mrg
363 1.1 mrg /* If their was no minimum, or this key is less than the min,
364 1.1 mrg it's the new min. */
365 1.1 mrg if (m_min == NULL || node->m_key < m_min->m_key)
366 1.1 mrg m_min = node;
367 1.1 mrg
368 1.1 mrg m_nodes++;
369 1.1 mrg
370 1.1 mrg return node;
371 1.1 mrg }
372 1.1 mrg
373 1.1 mrg /* For given NODE, set new KEY and DATA value. */
374 1.3 mrg
375 1.1 mrg template<class K, class V>
376 1.1 mrg V*
377 1.1 mrg fibonacci_heap<K,V>::replace_key_data (fibonacci_node<K,V> *node, K key,
378 1.1 mrg V *data)
379 1.1 mrg {
380 1.1 mrg K okey;
381 1.1 mrg fibonacci_node<K,V> *y;
382 1.1 mrg V *odata = node->m_data;
383 1.1 mrg
384 1.1 mrg /* If we wanted to, we do a real increase by redeleting and
385 1.1 mrg inserting. */
386 1.1 mrg if (node->compare_data (key) > 0)
387 1.1 mrg {
388 1.1 mrg delete_node (node, false);
389 1.1 mrg
390 1.1 mrg node = new (node) fibonacci_node_t ();
391 1.1 mrg insert (node, key, data);
392 1.1 mrg
393 1.1 mrg return odata;
394 1.1 mrg }
395 1.1 mrg
396 1.1 mrg okey = node->m_key;
397 1.1 mrg node->m_data = data;
398 1.1 mrg node->m_key = key;
399 1.1 mrg y = node->m_parent;
400 1.1 mrg
401 1.1 mrg /* Short-circuit if the key is the same, as we then don't have to
402 1.1 mrg do anything. Except if we're trying to force the new node to
403 1.1 mrg be the new minimum for delete. */
404 1.1 mrg if (okey == key && okey != m_global_min_key)
405 1.1 mrg return odata;
406 1.1 mrg
407 1.1 mrg /* These two compares are specifically <= 0 to make sure that in the case
408 1.1 mrg of equality, a node we replaced the data on, becomes the new min. This
409 1.1 mrg is needed so that delete's call to extractmin gets the right node. */
410 1.1 mrg if (y != NULL && node->compare (y) <= 0)
411 1.1 mrg {
412 1.1 mrg cut (node, y);
413 1.1 mrg cascading_cut (y);
414 1.1 mrg }
415 1.1 mrg
416 1.1 mrg if (node->compare (m_min) <= 0)
417 1.1 mrg m_min = node;
418 1.1 mrg
419 1.1 mrg return odata;
420 1.1 mrg }
421 1.1 mrg
422 1.3 mrg /* Extract minimum node in the heap. Delete fibonacci node if RELEASE
423 1.3 mrg is true. */
424 1.3 mrg
425 1.1 mrg template<class K, class V>
426 1.1 mrg V*
427 1.1 mrg fibonacci_heap<K,V>::extract_min (bool release)
428 1.1 mrg {
429 1.1 mrg fibonacci_node<K,V> *z;
430 1.1 mrg V *ret = NULL;
431 1.1 mrg
432 1.1 mrg /* If we don't have a min set, it means we have no nodes. */
433 1.1 mrg if (m_min != NULL)
434 1.1 mrg {
435 1.1 mrg /* Otherwise, extract the min node, free the node, and return the
436 1.1 mrg node's data. */
437 1.1 mrg z = extract_minimum_node ();
438 1.1 mrg ret = z->m_data;
439 1.1 mrg
440 1.1 mrg if (release)
441 1.1 mrg delete (z);
442 1.1 mrg }
443 1.1 mrg
444 1.1 mrg return ret;
445 1.1 mrg }
446 1.1 mrg
447 1.1 mrg /* Delete NODE in the heap, if RELEASE is specified memory is released. */
448 1.1 mrg
449 1.1 mrg template<class K, class V>
450 1.1 mrg V*
451 1.1 mrg fibonacci_heap<K,V>::delete_node (fibonacci_node<K,V> *node, bool release)
452 1.1 mrg {
453 1.1 mrg V *ret = node->m_data;
454 1.1 mrg
455 1.1 mrg /* To perform delete, we just make it the min key, and extract. */
456 1.1 mrg replace_key (node, m_global_min_key);
457 1.1 mrg if (node != m_min)
458 1.1 mrg {
459 1.1 mrg fprintf (stderr, "Can't force minimum on fibheap.\n");
460 1.1 mrg abort ();
461 1.1 mrg }
462 1.1 mrg extract_min (release);
463 1.1 mrg
464 1.1 mrg return ret;
465 1.1 mrg }
466 1.1 mrg
467 1.3 mrg /* Union the heap with HEAPB. One of the heaps is going to be deleted. */
468 1.1 mrg
469 1.1 mrg template<class K, class V>
470 1.1 mrg fibonacci_heap<K,V>*
471 1.1 mrg fibonacci_heap<K,V>::union_with (fibonacci_heap<K,V> *heapb)
472 1.1 mrg {
473 1.1 mrg fibonacci_heap<K,V> *heapa = this;
474 1.1 mrg
475 1.3 mrg fibonacci_node<K,V> *a_root, *b_root;
476 1.1 mrg
477 1.1 mrg /* If one of the heaps is empty, the union is just the other heap. */
478 1.1 mrg if ((a_root = heapa->m_root) == NULL)
479 1.1 mrg {
480 1.1 mrg delete (heapa);
481 1.1 mrg return heapb;
482 1.1 mrg }
483 1.1 mrg if ((b_root = heapb->m_root) == NULL)
484 1.1 mrg {
485 1.1 mrg delete (heapb);
486 1.1 mrg return heapa;
487 1.1 mrg }
488 1.1 mrg
489 1.1 mrg /* Merge them to the next nodes on the opposite chain. */
490 1.1 mrg a_root->m_left->m_right = b_root;
491 1.1 mrg b_root->m_left->m_right = a_root;
492 1.3 mrg std::swap (a_root->m_left, b_root->m_left);
493 1.1 mrg heapa->m_nodes += heapb->m_nodes;
494 1.1 mrg
495 1.1 mrg /* And set the new minimum, if it's changed. */
496 1.3 mrg if (heapb->m_min->compare (heapa->m_min) < 0)
497 1.1 mrg heapa->m_min = heapb->m_min;
498 1.1 mrg
499 1.3 mrg /* Set m_min to NULL to not to delete live fibonacci nodes. */
500 1.3 mrg heapb->m_min = NULL;
501 1.1 mrg delete (heapb);
502 1.3 mrg
503 1.1 mrg return heapa;
504 1.1 mrg }
505 1.1 mrg
506 1.1 mrg /* Insert it into the root list. */
507 1.1 mrg
508 1.1 mrg template<class K, class V>
509 1.1 mrg void
510 1.1 mrg fibonacci_heap<K,V>::insert_root (fibonacci_node_t *node)
511 1.1 mrg {
512 1.1 mrg /* If the heap is currently empty, the new node becomes the singleton
513 1.1 mrg circular root list. */
514 1.1 mrg if (m_root == NULL)
515 1.1 mrg {
516 1.1 mrg m_root = node;
517 1.1 mrg node->m_left = node;
518 1.1 mrg node->m_right = node;
519 1.1 mrg return;
520 1.1 mrg }
521 1.1 mrg
522 1.1 mrg /* Otherwise, insert it in the circular root list between the root
523 1.1 mrg and it's right node. */
524 1.1 mrg m_root->insert_after (node);
525 1.1 mrg }
526 1.1 mrg
527 1.1 mrg /* Remove NODE from PARENT's child list. */
528 1.1 mrg
529 1.1 mrg template<class K, class V>
530 1.1 mrg void
531 1.1 mrg fibonacci_heap<K,V>::cut (fibonacci_node<K,V> *node,
532 1.1 mrg fibonacci_node<K,V> *parent)
533 1.1 mrg {
534 1.1 mrg node->remove ();
535 1.1 mrg parent->m_degree--;
536 1.1 mrg insert_root (node);
537 1.1 mrg node->m_parent = NULL;
538 1.1 mrg node->m_mark = 0;
539 1.1 mrg }
540 1.1 mrg
541 1.1 mrg /* Process cut of node Y and do it recursivelly. */
542 1.1 mrg
543 1.1 mrg template<class K, class V>
544 1.1 mrg void
545 1.1 mrg fibonacci_heap<K,V>::cascading_cut (fibonacci_node<K,V> *y)
546 1.1 mrg {
547 1.1 mrg fibonacci_node<K,V> *z;
548 1.1 mrg
549 1.1 mrg while ((z = y->m_parent) != NULL)
550 1.1 mrg {
551 1.1 mrg if (y->m_mark == 0)
552 1.1 mrg {
553 1.1 mrg y->m_mark = 1;
554 1.1 mrg return;
555 1.1 mrg }
556 1.1 mrg else
557 1.1 mrg {
558 1.1 mrg cut (y, z);
559 1.1 mrg y = z;
560 1.1 mrg }
561 1.1 mrg }
562 1.1 mrg }
563 1.1 mrg
564 1.1 mrg /* Extract minimum node from the heap. */
565 1.3 mrg
566 1.1 mrg template<class K, class V>
567 1.1 mrg fibonacci_node<K,V>*
568 1.1 mrg fibonacci_heap<K,V>::extract_minimum_node ()
569 1.1 mrg {
570 1.1 mrg fibonacci_node<K,V> *ret = m_min;
571 1.1 mrg fibonacci_node<K,V> *x, *y, *orig;
572 1.1 mrg
573 1.1 mrg /* Attach the child list of the minimum node to the root list of the heap.
574 1.1 mrg If there is no child list, we don't do squat. */
575 1.1 mrg for (x = ret->m_child, orig = NULL; x != orig && x != NULL; x = y)
576 1.1 mrg {
577 1.1 mrg if (orig == NULL)
578 1.1 mrg orig = x;
579 1.1 mrg y = x->m_right;
580 1.1 mrg x->m_parent = NULL;
581 1.1 mrg insert_root (x);
582 1.1 mrg }
583 1.1 mrg
584 1.1 mrg /* Remove the old root. */
585 1.1 mrg remove_root (ret);
586 1.1 mrg m_nodes--;
587 1.1 mrg
588 1.1 mrg /* If we are left with no nodes, then the min is NULL. */
589 1.1 mrg if (m_nodes == 0)
590 1.1 mrg m_min = NULL;
591 1.1 mrg else
592 1.1 mrg {
593 1.1 mrg /* Otherwise, consolidate to find new minimum, as well as do the reorg
594 1.1 mrg work that needs to be done. */
595 1.1 mrg m_min = ret->m_right;
596 1.1 mrg consolidate ();
597 1.1 mrg }
598 1.1 mrg
599 1.1 mrg return ret;
600 1.1 mrg }
601 1.1 mrg
602 1.1 mrg /* Remove root NODE from the heap. */
603 1.1 mrg
604 1.1 mrg template<class K, class V>
605 1.1 mrg void
606 1.1 mrg fibonacci_heap<K,V>::remove_root (fibonacci_node<K,V> *node)
607 1.1 mrg {
608 1.1 mrg if (node->m_left == node)
609 1.1 mrg m_root = NULL;
610 1.1 mrg else
611 1.1 mrg m_root = node->remove ();
612 1.1 mrg }
613 1.1 mrg
614 1.1 mrg /* Consolidate heap. */
615 1.1 mrg
616 1.1 mrg template<class K, class V>
617 1.1 mrg void fibonacci_heap<K,V>::consolidate ()
618 1.1 mrg {
619 1.1 mrg int D = 1 + 8 * sizeof (long);
620 1.1 mrg auto_vec<fibonacci_node<K,V> *> a (D);
621 1.1 mrg a.safe_grow_cleared (D);
622 1.1 mrg fibonacci_node<K,V> *w, *x, *y;
623 1.1 mrg int i, d;
624 1.1 mrg
625 1.1 mrg while ((w = m_root) != NULL)
626 1.1 mrg {
627 1.1 mrg x = w;
628 1.1 mrg remove_root (w);
629 1.1 mrg d = x->m_degree;
630 1.1 mrg while (a[d] != NULL)
631 1.1 mrg {
632 1.1 mrg y = a[d];
633 1.1 mrg if (x->compare (y) > 0)
634 1.1 mrg std::swap (x, y);
635 1.1 mrg y->link (x);
636 1.1 mrg a[d] = NULL;
637 1.1 mrg d++;
638 1.1 mrg }
639 1.1 mrg a[d] = x;
640 1.1 mrg }
641 1.1 mrg m_min = NULL;
642 1.1 mrg for (i = 0; i < D; i++)
643 1.1 mrg if (a[i] != NULL)
644 1.1 mrg {
645 1.1 mrg insert_root (a[i]);
646 1.1 mrg if (m_min == NULL || a[i]->compare (m_min) < 0)
647 1.1 mrg m_min = a[i];
648 1.1 mrg }
649 1.1 mrg }
650 1.1 mrg
651 1.1 mrg #endif // GCC_FIBONACCI_HEAP_H
652