fibonacci_heap.h revision 1.1.1.1.2.1 1 1.1 mrg /* Vector API for GNU compiler.
2 1.1.1.1.2.1 pgoyette Copyright (C) 1998-2016 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.1 mrg fibonacci_node (K key): m_parent (NULL), m_child (NULL), m_left (this),
65 1.1 mrg m_right (this), m_key (key),
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.1 mrg /* Insert it into the root list. */
234 1.1 mrg void insert_root (fibonacci_node_t *node);
235 1.1 mrg
236 1.1 mrg /* Remove NODE from PARENT's child list. */
237 1.1 mrg void cut (fibonacci_node_t *node, fibonacci_node_t *parent);
238 1.1 mrg
239 1.1 mrg /* Process cut of node Y and do it recursivelly. */
240 1.1 mrg void cascading_cut (fibonacci_node_t *y);
241 1.1 mrg
242 1.1 mrg /* Extract minimum node from the heap. */
243 1.1 mrg fibonacci_node_t * extract_minimum_node ();
244 1.1 mrg
245 1.1 mrg /* Remove root NODE from the heap. */
246 1.1 mrg void remove_root (fibonacci_node_t *node);
247 1.1 mrg
248 1.1 mrg /* Consolidate heap. */
249 1.1 mrg void consolidate ();
250 1.1 mrg
251 1.1 mrg /* Number of nodes. */
252 1.1 mrg size_t m_nodes;
253 1.1 mrg /* Minimum node of the heap. */
254 1.1 mrg fibonacci_node_t *m_min;
255 1.1 mrg /* Root node of the heap. */
256 1.1 mrg fibonacci_node_t *m_root;
257 1.1 mrg /* Global minimum given in the heap construction. */
258 1.1 mrg K m_global_min_key;
259 1.1 mrg };
260 1.1 mrg
261 1.1 mrg /* Remove fibonacci heap node. */
262 1.1 mrg
263 1.1 mrg template<class K, class V>
264 1.1 mrg fibonacci_node<K,V> *
265 1.1 mrg fibonacci_node<K,V>::remove ()
266 1.1 mrg {
267 1.1 mrg fibonacci_node<K,V> *ret;
268 1.1 mrg
269 1.1 mrg if (this == m_left)
270 1.1 mrg ret = NULL;
271 1.1 mrg else
272 1.1 mrg ret = m_left;
273 1.1 mrg
274 1.1 mrg if (m_parent != NULL && m_parent->m_child == this)
275 1.1 mrg m_parent->m_child = ret;
276 1.1 mrg
277 1.1 mrg m_right->m_left = m_left;
278 1.1 mrg m_left->m_right = m_right;
279 1.1 mrg
280 1.1 mrg m_parent = NULL;
281 1.1 mrg m_left = this;
282 1.1 mrg m_right = this;
283 1.1 mrg
284 1.1 mrg return ret;
285 1.1 mrg }
286 1.1 mrg
287 1.1 mrg /* Link the node with PARENT. */
288 1.1 mrg
289 1.1 mrg template<class K, class V>
290 1.1 mrg void
291 1.1 mrg fibonacci_node<K,V>::link (fibonacci_node<K,V> *parent)
292 1.1 mrg {
293 1.1 mrg if (parent->m_child == NULL)
294 1.1 mrg parent->m_child = this;
295 1.1 mrg else
296 1.1 mrg parent->m_child->insert_before (this);
297 1.1 mrg m_parent = parent;
298 1.1 mrg parent->m_degree++;
299 1.1 mrg m_mark = 0;
300 1.1 mrg }
301 1.1 mrg
302 1.1 mrg /* Put node B after this node. */
303 1.1 mrg
304 1.1 mrg template<class K, class V>
305 1.1 mrg void
306 1.1 mrg fibonacci_node<K,V>::insert_after (fibonacci_node<K,V> *b)
307 1.1 mrg {
308 1.1 mrg fibonacci_node<K,V> *a = this;
309 1.1 mrg
310 1.1 mrg if (a == a->m_right)
311 1.1 mrg {
312 1.1 mrg a->m_right = b;
313 1.1 mrg a->m_left = b;
314 1.1 mrg b->m_right = a;
315 1.1 mrg b->m_left = a;
316 1.1 mrg }
317 1.1 mrg else
318 1.1 mrg {
319 1.1 mrg b->m_right = a->m_right;
320 1.1 mrg a->m_right->m_left = b;
321 1.1 mrg a->m_right = b;
322 1.1 mrg b->m_left = a;
323 1.1 mrg }
324 1.1 mrg }
325 1.1 mrg
326 1.1 mrg /* Insert new node given by KEY and DATA associated with the key. */
327 1.1 mrg
328 1.1 mrg template<class K, class V>
329 1.1 mrg fibonacci_node<K,V>*
330 1.1 mrg fibonacci_heap<K,V>::insert (K key, V *data)
331 1.1 mrg {
332 1.1 mrg /* Create the new node. */
333 1.1 mrg fibonacci_node<K,V> *node = new fibonacci_node_t ();
334 1.1 mrg
335 1.1 mrg return insert (node, key, data);
336 1.1 mrg }
337 1.1 mrg
338 1.1 mrg /* Insert new NODE given by KEY and DATA associated with the key. */
339 1.1 mrg
340 1.1 mrg template<class K, class V>
341 1.1 mrg fibonacci_node<K,V>*
342 1.1 mrg fibonacci_heap<K,V>::insert (fibonacci_node_t *node, K key, V *data)
343 1.1 mrg {
344 1.1 mrg /* Set the node's data. */
345 1.1 mrg node->m_data = data;
346 1.1 mrg node->m_key = key;
347 1.1 mrg
348 1.1 mrg /* Insert it into the root list. */
349 1.1 mrg insert_root (node);
350 1.1 mrg
351 1.1 mrg /* If their was no minimum, or this key is less than the min,
352 1.1 mrg it's the new min. */
353 1.1 mrg if (m_min == NULL || node->m_key < m_min->m_key)
354 1.1 mrg m_min = node;
355 1.1 mrg
356 1.1 mrg m_nodes++;
357 1.1 mrg
358 1.1 mrg return node;
359 1.1 mrg }
360 1.1 mrg
361 1.1 mrg /* For given NODE, set new KEY and DATA value. */
362 1.1 mrg template<class K, class V>
363 1.1 mrg V*
364 1.1 mrg fibonacci_heap<K,V>::replace_key_data (fibonacci_node<K,V> *node, K key,
365 1.1 mrg V *data)
366 1.1 mrg {
367 1.1 mrg K okey;
368 1.1 mrg fibonacci_node<K,V> *y;
369 1.1 mrg V *odata = node->m_data;
370 1.1 mrg
371 1.1 mrg /* If we wanted to, we do a real increase by redeleting and
372 1.1 mrg inserting. */
373 1.1 mrg if (node->compare_data (key) > 0)
374 1.1 mrg {
375 1.1 mrg delete_node (node, false);
376 1.1 mrg
377 1.1 mrg node = new (node) fibonacci_node_t ();
378 1.1 mrg insert (node, key, data);
379 1.1 mrg
380 1.1 mrg return odata;
381 1.1 mrg }
382 1.1 mrg
383 1.1 mrg okey = node->m_key;
384 1.1 mrg node->m_data = data;
385 1.1 mrg node->m_key = key;
386 1.1 mrg y = node->m_parent;
387 1.1 mrg
388 1.1 mrg /* Short-circuit if the key is the same, as we then don't have to
389 1.1 mrg do anything. Except if we're trying to force the new node to
390 1.1 mrg be the new minimum for delete. */
391 1.1 mrg if (okey == key && okey != m_global_min_key)
392 1.1 mrg return odata;
393 1.1 mrg
394 1.1 mrg /* These two compares are specifically <= 0 to make sure that in the case
395 1.1 mrg of equality, a node we replaced the data on, becomes the new min. This
396 1.1 mrg is needed so that delete's call to extractmin gets the right node. */
397 1.1 mrg if (y != NULL && node->compare (y) <= 0)
398 1.1 mrg {
399 1.1 mrg cut (node, y);
400 1.1 mrg cascading_cut (y);
401 1.1 mrg }
402 1.1 mrg
403 1.1 mrg if (node->compare (m_min) <= 0)
404 1.1 mrg m_min = node;
405 1.1 mrg
406 1.1 mrg return odata;
407 1.1 mrg }
408 1.1 mrg
409 1.1 mrg /* Extract minimum node in the heap. */
410 1.1 mrg template<class K, class V>
411 1.1 mrg V*
412 1.1 mrg fibonacci_heap<K,V>::extract_min (bool release)
413 1.1 mrg {
414 1.1 mrg fibonacci_node<K,V> *z;
415 1.1 mrg V *ret = NULL;
416 1.1 mrg
417 1.1 mrg /* If we don't have a min set, it means we have no nodes. */
418 1.1 mrg if (m_min != NULL)
419 1.1 mrg {
420 1.1 mrg /* Otherwise, extract the min node, free the node, and return the
421 1.1 mrg node's data. */
422 1.1 mrg z = extract_minimum_node ();
423 1.1 mrg ret = z->m_data;
424 1.1 mrg
425 1.1 mrg if (release)
426 1.1 mrg delete (z);
427 1.1 mrg }
428 1.1 mrg
429 1.1 mrg return ret;
430 1.1 mrg }
431 1.1 mrg
432 1.1 mrg /* Delete NODE in the heap, if RELEASE is specified memory is released. */
433 1.1 mrg
434 1.1 mrg template<class K, class V>
435 1.1 mrg V*
436 1.1 mrg fibonacci_heap<K,V>::delete_node (fibonacci_node<K,V> *node, bool release)
437 1.1 mrg {
438 1.1 mrg V *ret = node->m_data;
439 1.1 mrg
440 1.1 mrg /* To perform delete, we just make it the min key, and extract. */
441 1.1 mrg replace_key (node, m_global_min_key);
442 1.1 mrg if (node != m_min)
443 1.1 mrg {
444 1.1 mrg fprintf (stderr, "Can't force minimum on fibheap.\n");
445 1.1 mrg abort ();
446 1.1 mrg }
447 1.1 mrg extract_min (release);
448 1.1 mrg
449 1.1 mrg return ret;
450 1.1 mrg }
451 1.1 mrg
452 1.1 mrg /* Union the heap with HEAPB. */
453 1.1 mrg
454 1.1 mrg template<class K, class V>
455 1.1 mrg fibonacci_heap<K,V>*
456 1.1 mrg fibonacci_heap<K,V>::union_with (fibonacci_heap<K,V> *heapb)
457 1.1 mrg {
458 1.1 mrg fibonacci_heap<K,V> *heapa = this;
459 1.1 mrg
460 1.1.1.1.2.1 pgoyette fibonacci_node<K,V> *a_root, *b_root;
461 1.1 mrg
462 1.1 mrg /* If one of the heaps is empty, the union is just the other heap. */
463 1.1 mrg if ((a_root = heapa->m_root) == NULL)
464 1.1 mrg {
465 1.1 mrg delete (heapa);
466 1.1 mrg return heapb;
467 1.1 mrg }
468 1.1 mrg if ((b_root = heapb->m_root) == NULL)
469 1.1 mrg {
470 1.1 mrg delete (heapb);
471 1.1 mrg return heapa;
472 1.1 mrg }
473 1.1 mrg
474 1.1 mrg /* Merge them to the next nodes on the opposite chain. */
475 1.1 mrg a_root->m_left->m_right = b_root;
476 1.1 mrg b_root->m_left->m_right = a_root;
477 1.1.1.1.2.1 pgoyette std::swap (a_root->m_left, b_root->m_left);
478 1.1 mrg heapa->m_nodes += heapb->m_nodes;
479 1.1 mrg
480 1.1 mrg /* And set the new minimum, if it's changed. */
481 1.1 mrg if (heapb->min->compare (heapa->min) < 0)
482 1.1 mrg heapa->m_min = heapb->m_min;
483 1.1 mrg
484 1.1 mrg delete (heapb);
485 1.1 mrg return heapa;
486 1.1 mrg }
487 1.1 mrg
488 1.1 mrg /* Insert it into the root list. */
489 1.1 mrg
490 1.1 mrg template<class K, class V>
491 1.1 mrg void
492 1.1 mrg fibonacci_heap<K,V>::insert_root (fibonacci_node_t *node)
493 1.1 mrg {
494 1.1 mrg /* If the heap is currently empty, the new node becomes the singleton
495 1.1 mrg circular root list. */
496 1.1 mrg if (m_root == NULL)
497 1.1 mrg {
498 1.1 mrg m_root = node;
499 1.1 mrg node->m_left = node;
500 1.1 mrg node->m_right = node;
501 1.1 mrg return;
502 1.1 mrg }
503 1.1 mrg
504 1.1 mrg /* Otherwise, insert it in the circular root list between the root
505 1.1 mrg and it's right node. */
506 1.1 mrg m_root->insert_after (node);
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg /* Remove NODE from PARENT's child list. */
510 1.1 mrg
511 1.1 mrg template<class K, class V>
512 1.1 mrg void
513 1.1 mrg fibonacci_heap<K,V>::cut (fibonacci_node<K,V> *node,
514 1.1 mrg fibonacci_node<K,V> *parent)
515 1.1 mrg {
516 1.1 mrg node->remove ();
517 1.1 mrg parent->m_degree--;
518 1.1 mrg insert_root (node);
519 1.1 mrg node->m_parent = NULL;
520 1.1 mrg node->m_mark = 0;
521 1.1 mrg }
522 1.1 mrg
523 1.1 mrg /* Process cut of node Y and do it recursivelly. */
524 1.1 mrg
525 1.1 mrg template<class K, class V>
526 1.1 mrg void
527 1.1 mrg fibonacci_heap<K,V>::cascading_cut (fibonacci_node<K,V> *y)
528 1.1 mrg {
529 1.1 mrg fibonacci_node<K,V> *z;
530 1.1 mrg
531 1.1 mrg while ((z = y->m_parent) != NULL)
532 1.1 mrg {
533 1.1 mrg if (y->m_mark == 0)
534 1.1 mrg {
535 1.1 mrg y->m_mark = 1;
536 1.1 mrg return;
537 1.1 mrg }
538 1.1 mrg else
539 1.1 mrg {
540 1.1 mrg cut (y, z);
541 1.1 mrg y = z;
542 1.1 mrg }
543 1.1 mrg }
544 1.1 mrg }
545 1.1 mrg
546 1.1 mrg /* Extract minimum node from the heap. */
547 1.1 mrg template<class K, class V>
548 1.1 mrg fibonacci_node<K,V>*
549 1.1 mrg fibonacci_heap<K,V>::extract_minimum_node ()
550 1.1 mrg {
551 1.1 mrg fibonacci_node<K,V> *ret = m_min;
552 1.1 mrg fibonacci_node<K,V> *x, *y, *orig;
553 1.1 mrg
554 1.1 mrg /* Attach the child list of the minimum node to the root list of the heap.
555 1.1 mrg If there is no child list, we don't do squat. */
556 1.1 mrg for (x = ret->m_child, orig = NULL; x != orig && x != NULL; x = y)
557 1.1 mrg {
558 1.1 mrg if (orig == NULL)
559 1.1 mrg orig = x;
560 1.1 mrg y = x->m_right;
561 1.1 mrg x->m_parent = NULL;
562 1.1 mrg insert_root (x);
563 1.1 mrg }
564 1.1 mrg
565 1.1 mrg /* Remove the old root. */
566 1.1 mrg remove_root (ret);
567 1.1 mrg m_nodes--;
568 1.1 mrg
569 1.1 mrg /* If we are left with no nodes, then the min is NULL. */
570 1.1 mrg if (m_nodes == 0)
571 1.1 mrg m_min = NULL;
572 1.1 mrg else
573 1.1 mrg {
574 1.1 mrg /* Otherwise, consolidate to find new minimum, as well as do the reorg
575 1.1 mrg work that needs to be done. */
576 1.1 mrg m_min = ret->m_right;
577 1.1 mrg consolidate ();
578 1.1 mrg }
579 1.1 mrg
580 1.1 mrg return ret;
581 1.1 mrg }
582 1.1 mrg
583 1.1 mrg /* Remove root NODE from the heap. */
584 1.1 mrg
585 1.1 mrg template<class K, class V>
586 1.1 mrg void
587 1.1 mrg fibonacci_heap<K,V>::remove_root (fibonacci_node<K,V> *node)
588 1.1 mrg {
589 1.1 mrg if (node->m_left == node)
590 1.1 mrg m_root = NULL;
591 1.1 mrg else
592 1.1 mrg m_root = node->remove ();
593 1.1 mrg }
594 1.1 mrg
595 1.1 mrg /* Consolidate heap. */
596 1.1 mrg
597 1.1 mrg template<class K, class V>
598 1.1 mrg void fibonacci_heap<K,V>::consolidate ()
599 1.1 mrg {
600 1.1 mrg int D = 1 + 8 * sizeof (long);
601 1.1 mrg auto_vec<fibonacci_node<K,V> *> a (D);
602 1.1 mrg a.safe_grow_cleared (D);
603 1.1 mrg fibonacci_node<K,V> *w, *x, *y;
604 1.1 mrg int i, d;
605 1.1 mrg
606 1.1 mrg while ((w = m_root) != NULL)
607 1.1 mrg {
608 1.1 mrg x = w;
609 1.1 mrg remove_root (w);
610 1.1 mrg d = x->m_degree;
611 1.1 mrg while (a[d] != NULL)
612 1.1 mrg {
613 1.1 mrg y = a[d];
614 1.1 mrg if (x->compare (y) > 0)
615 1.1 mrg std::swap (x, y);
616 1.1 mrg y->link (x);
617 1.1 mrg a[d] = NULL;
618 1.1 mrg d++;
619 1.1 mrg }
620 1.1 mrg a[d] = x;
621 1.1 mrg }
622 1.1 mrg m_min = NULL;
623 1.1 mrg for (i = 0; i < D; i++)
624 1.1 mrg if (a[i] != NULL)
625 1.1 mrg {
626 1.1 mrg insert_root (a[i]);
627 1.1 mrg if (m_min == NULL || a[i]->compare (m_min) < 0)
628 1.1 mrg m_min = a[i];
629 1.1 mrg }
630 1.1 mrg }
631 1.1 mrg
632 1.1 mrg #endif // GCC_FIBONACCI_HEAP_H
633