xref: /dflybsd-src/contrib/binutils-2.27/libiberty/fibheap.c (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj /* A Fibonacci heap datatype.
2*a9fa9459Szrj    Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3*a9fa9459Szrj    Contributed by Daniel Berlin (dan@cgsoftware.com).
4*a9fa9459Szrj 
5*a9fa9459Szrj This file is part of GNU CC.
6*a9fa9459Szrj 
7*a9fa9459Szrj GNU CC is free software; you can redistribute it and/or modify it
8*a9fa9459Szrj under the terms of the GNU General Public License as published by
9*a9fa9459Szrj the Free Software Foundation; either version 2, or (at your option)
10*a9fa9459Szrj any later version.
11*a9fa9459Szrj 
12*a9fa9459Szrj GNU CC is distributed in the hope that it will be useful, but
13*a9fa9459Szrj WITHOUT ANY WARRANTY; without even the implied warranty of
14*a9fa9459Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*a9fa9459Szrj General Public License for more details.
16*a9fa9459Szrj 
17*a9fa9459Szrj You should have received a copy of the GNU General Public License
18*a9fa9459Szrj along with GNU CC; see the file COPYING.  If not, write to
19*a9fa9459Szrj the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20*a9fa9459Szrj Boston, MA 02110-1301, USA.  */
21*a9fa9459Szrj 
22*a9fa9459Szrj #ifdef HAVE_CONFIG_H
23*a9fa9459Szrj #include "config.h"
24*a9fa9459Szrj #endif
25*a9fa9459Szrj #ifdef HAVE_LIMITS_H
26*a9fa9459Szrj #include <limits.h>
27*a9fa9459Szrj #endif
28*a9fa9459Szrj #ifdef HAVE_STDLIB_H
29*a9fa9459Szrj #include <stdlib.h>
30*a9fa9459Szrj #endif
31*a9fa9459Szrj #ifdef HAVE_STRING_H
32*a9fa9459Szrj #include <string.h>
33*a9fa9459Szrj #endif
34*a9fa9459Szrj #include "libiberty.h"
35*a9fa9459Szrj #include "fibheap.h"
36*a9fa9459Szrj 
37*a9fa9459Szrj 
38*a9fa9459Szrj #define FIBHEAPKEY_MIN	LONG_MIN
39*a9fa9459Szrj 
40*a9fa9459Szrj static void fibheap_ins_root (fibheap_t, fibnode_t);
41*a9fa9459Szrj static void fibheap_rem_root (fibheap_t, fibnode_t);
42*a9fa9459Szrj static void fibheap_consolidate (fibheap_t);
43*a9fa9459Szrj static void fibheap_link (fibheap_t, fibnode_t, fibnode_t);
44*a9fa9459Szrj static void fibheap_cut (fibheap_t, fibnode_t, fibnode_t);
45*a9fa9459Szrj static void fibheap_cascading_cut (fibheap_t, fibnode_t);
46*a9fa9459Szrj static fibnode_t fibheap_extr_min_node (fibheap_t);
47*a9fa9459Szrj static int fibheap_compare (fibheap_t, fibnode_t, fibnode_t);
48*a9fa9459Szrj static int fibheap_comp_data (fibheap_t, fibheapkey_t, void *, fibnode_t);
49*a9fa9459Szrj static fibnode_t fibnode_new (void);
50*a9fa9459Szrj static void fibnode_insert_after (fibnode_t, fibnode_t);
51*a9fa9459Szrj #define fibnode_insert_before(a, b) fibnode_insert_after (a->left, b)
52*a9fa9459Szrj static fibnode_t fibnode_remove (fibnode_t);
53*a9fa9459Szrj 
54*a9fa9459Szrj 
55*a9fa9459Szrj /* Create a new fibonacci heap.  */
56*a9fa9459Szrj fibheap_t
fibheap_new(void)57*a9fa9459Szrj fibheap_new (void)
58*a9fa9459Szrj {
59*a9fa9459Szrj   return (fibheap_t) xcalloc (1, sizeof (struct fibheap));
60*a9fa9459Szrj }
61*a9fa9459Szrj 
62*a9fa9459Szrj /* Create a new fibonacci heap node.  */
63*a9fa9459Szrj static fibnode_t
fibnode_new(void)64*a9fa9459Szrj fibnode_new (void)
65*a9fa9459Szrj {
66*a9fa9459Szrj   fibnode_t node;
67*a9fa9459Szrj 
68*a9fa9459Szrj   node = (fibnode_t) xcalloc (1, sizeof *node);
69*a9fa9459Szrj   node->left = node;
70*a9fa9459Szrj   node->right = node;
71*a9fa9459Szrj 
72*a9fa9459Szrj   return node;
73*a9fa9459Szrj }
74*a9fa9459Szrj 
75*a9fa9459Szrj static inline int
fibheap_compare(fibheap_t heap ATTRIBUTE_UNUSED,fibnode_t a,fibnode_t b)76*a9fa9459Szrj fibheap_compare (fibheap_t heap ATTRIBUTE_UNUSED, fibnode_t a, fibnode_t b)
77*a9fa9459Szrj {
78*a9fa9459Szrj   if (a->key < b->key)
79*a9fa9459Szrj     return -1;
80*a9fa9459Szrj   if (a->key > b->key)
81*a9fa9459Szrj     return 1;
82*a9fa9459Szrj   return 0;
83*a9fa9459Szrj }
84*a9fa9459Szrj 
85*a9fa9459Szrj static inline int
fibheap_comp_data(fibheap_t heap,fibheapkey_t key,void * data,fibnode_t b)86*a9fa9459Szrj fibheap_comp_data (fibheap_t heap, fibheapkey_t key, void *data, fibnode_t b)
87*a9fa9459Szrj {
88*a9fa9459Szrj   struct fibnode a;
89*a9fa9459Szrj 
90*a9fa9459Szrj   a.key = key;
91*a9fa9459Szrj   a.data = data;
92*a9fa9459Szrj 
93*a9fa9459Szrj   return fibheap_compare (heap, &a, b);
94*a9fa9459Szrj }
95*a9fa9459Szrj 
96*a9fa9459Szrj /* Insert DATA, with priority KEY, into HEAP.  */
97*a9fa9459Szrj fibnode_t
fibheap_insert(fibheap_t heap,fibheapkey_t key,void * data)98*a9fa9459Szrj fibheap_insert (fibheap_t heap, fibheapkey_t key, void *data)
99*a9fa9459Szrj {
100*a9fa9459Szrj   fibnode_t node;
101*a9fa9459Szrj 
102*a9fa9459Szrj   /* Create the new node.  */
103*a9fa9459Szrj   node = fibnode_new ();
104*a9fa9459Szrj 
105*a9fa9459Szrj   /* Set the node's data.  */
106*a9fa9459Szrj   node->data = data;
107*a9fa9459Szrj   node->key = key;
108*a9fa9459Szrj 
109*a9fa9459Szrj   /* Insert it into the root list.  */
110*a9fa9459Szrj   fibheap_ins_root (heap, node);
111*a9fa9459Szrj 
112*a9fa9459Szrj   /* If their was no minimum, or this key is less than the min,
113*a9fa9459Szrj      it's the new min.  */
114*a9fa9459Szrj   if (heap->min == NULL || node->key < heap->min->key)
115*a9fa9459Szrj     heap->min = node;
116*a9fa9459Szrj 
117*a9fa9459Szrj   heap->nodes++;
118*a9fa9459Szrj 
119*a9fa9459Szrj   return node;
120*a9fa9459Szrj }
121*a9fa9459Szrj 
122*a9fa9459Szrj /* Return the data of the minimum node (if we know it).  */
123*a9fa9459Szrj void *
fibheap_min(fibheap_t heap)124*a9fa9459Szrj fibheap_min (fibheap_t heap)
125*a9fa9459Szrj {
126*a9fa9459Szrj   /* If there is no min, we can't easily return it.  */
127*a9fa9459Szrj   if (heap->min == NULL)
128*a9fa9459Szrj     return NULL;
129*a9fa9459Szrj   return heap->min->data;
130*a9fa9459Szrj }
131*a9fa9459Szrj 
132*a9fa9459Szrj /* Return the key of the minimum node (if we know it).  */
133*a9fa9459Szrj fibheapkey_t
fibheap_min_key(fibheap_t heap)134*a9fa9459Szrj fibheap_min_key (fibheap_t heap)
135*a9fa9459Szrj {
136*a9fa9459Szrj   /* If there is no min, we can't easily return it.  */
137*a9fa9459Szrj   if (heap->min == NULL)
138*a9fa9459Szrj     return 0;
139*a9fa9459Szrj   return heap->min->key;
140*a9fa9459Szrj }
141*a9fa9459Szrj 
142*a9fa9459Szrj /* Union HEAPA and HEAPB into a new heap.  */
143*a9fa9459Szrj fibheap_t
fibheap_union(fibheap_t heapa,fibheap_t heapb)144*a9fa9459Szrj fibheap_union (fibheap_t heapa, fibheap_t heapb)
145*a9fa9459Szrj {
146*a9fa9459Szrj   fibnode_t a_root, b_root, temp;
147*a9fa9459Szrj 
148*a9fa9459Szrj   /* If one of the heaps is empty, the union is just the other heap.  */
149*a9fa9459Szrj   if ((a_root = heapa->root) == NULL)
150*a9fa9459Szrj     {
151*a9fa9459Szrj       free (heapa);
152*a9fa9459Szrj       return heapb;
153*a9fa9459Szrj     }
154*a9fa9459Szrj   if ((b_root = heapb->root) == NULL)
155*a9fa9459Szrj     {
156*a9fa9459Szrj       free (heapb);
157*a9fa9459Szrj       return heapa;
158*a9fa9459Szrj     }
159*a9fa9459Szrj 
160*a9fa9459Szrj   /* Merge them to the next nodes on the opposite chain.  */
161*a9fa9459Szrj   a_root->left->right = b_root;
162*a9fa9459Szrj   b_root->left->right = a_root;
163*a9fa9459Szrj   temp = a_root->left;
164*a9fa9459Szrj   a_root->left = b_root->left;
165*a9fa9459Szrj   b_root->left = temp;
166*a9fa9459Szrj   heapa->nodes += heapb->nodes;
167*a9fa9459Szrj 
168*a9fa9459Szrj   /* And set the new minimum, if it's changed.  */
169*a9fa9459Szrj   if (fibheap_compare (heapa, heapb->min, heapa->min) < 0)
170*a9fa9459Szrj     heapa->min = heapb->min;
171*a9fa9459Szrj 
172*a9fa9459Szrj   free (heapb);
173*a9fa9459Szrj   return heapa;
174*a9fa9459Szrj }
175*a9fa9459Szrj 
176*a9fa9459Szrj /* Extract the data of the minimum node from HEAP.  */
177*a9fa9459Szrj void *
fibheap_extract_min(fibheap_t heap)178*a9fa9459Szrj fibheap_extract_min (fibheap_t heap)
179*a9fa9459Szrj {
180*a9fa9459Szrj   fibnode_t z;
181*a9fa9459Szrj   void *ret = NULL;
182*a9fa9459Szrj 
183*a9fa9459Szrj   /* If we don't have a min set, it means we have no nodes.  */
184*a9fa9459Szrj   if (heap->min != NULL)
185*a9fa9459Szrj     {
186*a9fa9459Szrj       /* Otherwise, extract the min node, free the node, and return the
187*a9fa9459Szrj          node's data.  */
188*a9fa9459Szrj       z = fibheap_extr_min_node (heap);
189*a9fa9459Szrj       ret = z->data;
190*a9fa9459Szrj       free (z);
191*a9fa9459Szrj     }
192*a9fa9459Szrj 
193*a9fa9459Szrj   return ret;
194*a9fa9459Szrj }
195*a9fa9459Szrj 
196*a9fa9459Szrj /* Replace both the KEY and the DATA associated with NODE.  */
197*a9fa9459Szrj void *
fibheap_replace_key_data(fibheap_t heap,fibnode_t node,fibheapkey_t key,void * data)198*a9fa9459Szrj fibheap_replace_key_data (fibheap_t heap, fibnode_t node,
199*a9fa9459Szrj                           fibheapkey_t key, void *data)
200*a9fa9459Szrj {
201*a9fa9459Szrj   void *odata;
202*a9fa9459Szrj   fibheapkey_t okey;
203*a9fa9459Szrj   fibnode_t y;
204*a9fa9459Szrj 
205*a9fa9459Szrj   /* If we wanted to, we could actually do a real increase by redeleting and
206*a9fa9459Szrj      inserting. However, this would require O (log n) time. So just bail out
207*a9fa9459Szrj      for now.  */
208*a9fa9459Szrj   if (fibheap_comp_data (heap, key, data, node) > 0)
209*a9fa9459Szrj     return NULL;
210*a9fa9459Szrj 
211*a9fa9459Szrj   odata = node->data;
212*a9fa9459Szrj   okey = node->key;
213*a9fa9459Szrj   node->data = data;
214*a9fa9459Szrj   node->key = key;
215*a9fa9459Szrj   y = node->parent;
216*a9fa9459Szrj 
217*a9fa9459Szrj   /* Short-circuit if the key is the same, as we then don't have to
218*a9fa9459Szrj      do anything.  Except if we're trying to force the new node to
219*a9fa9459Szrj      be the new minimum for delete.  */
220*a9fa9459Szrj   if (okey == key && okey != FIBHEAPKEY_MIN)
221*a9fa9459Szrj     return odata;
222*a9fa9459Szrj 
223*a9fa9459Szrj   /* These two compares are specifically <= 0 to make sure that in the case
224*a9fa9459Szrj      of equality, a node we replaced the data on, becomes the new min.  This
225*a9fa9459Szrj      is needed so that delete's call to extractmin gets the right node.  */
226*a9fa9459Szrj   if (y != NULL && fibheap_compare (heap, node, y) <= 0)
227*a9fa9459Szrj     {
228*a9fa9459Szrj       fibheap_cut (heap, node, y);
229*a9fa9459Szrj       fibheap_cascading_cut (heap, y);
230*a9fa9459Szrj     }
231*a9fa9459Szrj 
232*a9fa9459Szrj   if (fibheap_compare (heap, node, heap->min) <= 0)
233*a9fa9459Szrj     heap->min = node;
234*a9fa9459Szrj 
235*a9fa9459Szrj   return odata;
236*a9fa9459Szrj }
237*a9fa9459Szrj 
238*a9fa9459Szrj /* Replace the DATA associated with NODE.  */
239*a9fa9459Szrj void *
fibheap_replace_data(fibheap_t heap,fibnode_t node,void * data)240*a9fa9459Szrj fibheap_replace_data (fibheap_t heap, fibnode_t node, void *data)
241*a9fa9459Szrj {
242*a9fa9459Szrj   return fibheap_replace_key_data (heap, node, node->key, data);
243*a9fa9459Szrj }
244*a9fa9459Szrj 
245*a9fa9459Szrj /* Replace the KEY associated with NODE.  */
246*a9fa9459Szrj fibheapkey_t
fibheap_replace_key(fibheap_t heap,fibnode_t node,fibheapkey_t key)247*a9fa9459Szrj fibheap_replace_key (fibheap_t heap, fibnode_t node, fibheapkey_t key)
248*a9fa9459Szrj {
249*a9fa9459Szrj   int okey = node->key;
250*a9fa9459Szrj   fibheap_replace_key_data (heap, node, key, node->data);
251*a9fa9459Szrj   return okey;
252*a9fa9459Szrj }
253*a9fa9459Szrj 
254*a9fa9459Szrj /* Delete NODE from HEAP.  */
255*a9fa9459Szrj void *
fibheap_delete_node(fibheap_t heap,fibnode_t node)256*a9fa9459Szrj fibheap_delete_node (fibheap_t heap, fibnode_t node)
257*a9fa9459Szrj {
258*a9fa9459Szrj   void *ret = node->data;
259*a9fa9459Szrj 
260*a9fa9459Szrj   /* To perform delete, we just make it the min key, and extract.  */
261*a9fa9459Szrj   fibheap_replace_key (heap, node, FIBHEAPKEY_MIN);
262*a9fa9459Szrj   if (node != heap->min)
263*a9fa9459Szrj     {
264*a9fa9459Szrj       fprintf (stderr, "Can't force minimum on fibheap.\n");
265*a9fa9459Szrj       abort ();
266*a9fa9459Szrj     }
267*a9fa9459Szrj   fibheap_extract_min (heap);
268*a9fa9459Szrj 
269*a9fa9459Szrj   return ret;
270*a9fa9459Szrj }
271*a9fa9459Szrj 
272*a9fa9459Szrj /* Delete HEAP.  */
273*a9fa9459Szrj void
fibheap_delete(fibheap_t heap)274*a9fa9459Szrj fibheap_delete (fibheap_t heap)
275*a9fa9459Szrj {
276*a9fa9459Szrj   while (heap->min != NULL)
277*a9fa9459Szrj     free (fibheap_extr_min_node (heap));
278*a9fa9459Szrj 
279*a9fa9459Szrj   free (heap);
280*a9fa9459Szrj }
281*a9fa9459Szrj 
282*a9fa9459Szrj /* Determine if HEAP is empty.  */
283*a9fa9459Szrj int
fibheap_empty(fibheap_t heap)284*a9fa9459Szrj fibheap_empty (fibheap_t heap)
285*a9fa9459Szrj {
286*a9fa9459Szrj   return heap->nodes == 0;
287*a9fa9459Szrj }
288*a9fa9459Szrj 
289*a9fa9459Szrj /* Extract the minimum node of the heap.  */
290*a9fa9459Szrj static fibnode_t
fibheap_extr_min_node(fibheap_t heap)291*a9fa9459Szrj fibheap_extr_min_node (fibheap_t heap)
292*a9fa9459Szrj {
293*a9fa9459Szrj   fibnode_t ret = heap->min;
294*a9fa9459Szrj   fibnode_t x, y, orig;
295*a9fa9459Szrj 
296*a9fa9459Szrj   /* Attach the child list of the minimum node to the root list of the heap.
297*a9fa9459Szrj      If there is no child list, we don't do squat.  */
298*a9fa9459Szrj   for (x = ret->child, orig = NULL; x != orig && x != NULL; x = y)
299*a9fa9459Szrj     {
300*a9fa9459Szrj       if (orig == NULL)
301*a9fa9459Szrj 	orig = x;
302*a9fa9459Szrj       y = x->right;
303*a9fa9459Szrj       x->parent = NULL;
304*a9fa9459Szrj       fibheap_ins_root (heap, x);
305*a9fa9459Szrj     }
306*a9fa9459Szrj 
307*a9fa9459Szrj   /* Remove the old root.  */
308*a9fa9459Szrj   fibheap_rem_root (heap, ret);
309*a9fa9459Szrj   heap->nodes--;
310*a9fa9459Szrj 
311*a9fa9459Szrj   /* If we are left with no nodes, then the min is NULL.  */
312*a9fa9459Szrj   if (heap->nodes == 0)
313*a9fa9459Szrj     heap->min = NULL;
314*a9fa9459Szrj   else
315*a9fa9459Szrj     {
316*a9fa9459Szrj       /* Otherwise, consolidate to find new minimum, as well as do the reorg
317*a9fa9459Szrj          work that needs to be done.  */
318*a9fa9459Szrj       heap->min = ret->right;
319*a9fa9459Szrj       fibheap_consolidate (heap);
320*a9fa9459Szrj     }
321*a9fa9459Szrj 
322*a9fa9459Szrj   return ret;
323*a9fa9459Szrj }
324*a9fa9459Szrj 
325*a9fa9459Szrj /* Insert NODE into the root list of HEAP.  */
326*a9fa9459Szrj static void
fibheap_ins_root(fibheap_t heap,fibnode_t node)327*a9fa9459Szrj fibheap_ins_root (fibheap_t heap, fibnode_t node)
328*a9fa9459Szrj {
329*a9fa9459Szrj   /* If the heap is currently empty, the new node becomes the singleton
330*a9fa9459Szrj      circular root list.  */
331*a9fa9459Szrj   if (heap->root == NULL)
332*a9fa9459Szrj     {
333*a9fa9459Szrj       heap->root = node;
334*a9fa9459Szrj       node->left = node;
335*a9fa9459Szrj       node->right = node;
336*a9fa9459Szrj       return;
337*a9fa9459Szrj     }
338*a9fa9459Szrj 
339*a9fa9459Szrj   /* Otherwise, insert it in the circular root list between the root
340*a9fa9459Szrj      and it's right node.  */
341*a9fa9459Szrj   fibnode_insert_after (heap->root, node);
342*a9fa9459Szrj }
343*a9fa9459Szrj 
344*a9fa9459Szrj /* Remove NODE from the rootlist of HEAP.  */
345*a9fa9459Szrj static void
fibheap_rem_root(fibheap_t heap,fibnode_t node)346*a9fa9459Szrj fibheap_rem_root (fibheap_t heap, fibnode_t node)
347*a9fa9459Szrj {
348*a9fa9459Szrj   if (node->left == node)
349*a9fa9459Szrj     heap->root = NULL;
350*a9fa9459Szrj   else
351*a9fa9459Szrj     heap->root = fibnode_remove (node);
352*a9fa9459Szrj }
353*a9fa9459Szrj 
354*a9fa9459Szrj /* Consolidate the heap.  */
355*a9fa9459Szrj static void
fibheap_consolidate(fibheap_t heap)356*a9fa9459Szrj fibheap_consolidate (fibheap_t heap)
357*a9fa9459Szrj {
358*a9fa9459Szrj   fibnode_t a[1 + 8 * sizeof (long)];
359*a9fa9459Szrj   fibnode_t w;
360*a9fa9459Szrj   fibnode_t y;
361*a9fa9459Szrj   fibnode_t x;
362*a9fa9459Szrj   int i;
363*a9fa9459Szrj   int d;
364*a9fa9459Szrj   int D;
365*a9fa9459Szrj 
366*a9fa9459Szrj   D = 1 + 8 * sizeof (long);
367*a9fa9459Szrj 
368*a9fa9459Szrj   memset (a, 0, sizeof (fibnode_t) * D);
369*a9fa9459Szrj 
370*a9fa9459Szrj   while ((w = heap->root) != NULL)
371*a9fa9459Szrj     {
372*a9fa9459Szrj       x = w;
373*a9fa9459Szrj       fibheap_rem_root (heap, w);
374*a9fa9459Szrj       d = x->degree;
375*a9fa9459Szrj       while (a[d] != NULL)
376*a9fa9459Szrj 	{
377*a9fa9459Szrj 	  y = a[d];
378*a9fa9459Szrj 	  if (fibheap_compare (heap, x, y) > 0)
379*a9fa9459Szrj 	    {
380*a9fa9459Szrj 	      fibnode_t temp;
381*a9fa9459Szrj 	      temp = x;
382*a9fa9459Szrj 	      x = y;
383*a9fa9459Szrj 	      y = temp;
384*a9fa9459Szrj 	    }
385*a9fa9459Szrj 	  fibheap_link (heap, y, x);
386*a9fa9459Szrj 	  a[d] = NULL;
387*a9fa9459Szrj 	  d++;
388*a9fa9459Szrj 	}
389*a9fa9459Szrj       a[d] = x;
390*a9fa9459Szrj     }
391*a9fa9459Szrj   heap->min = NULL;
392*a9fa9459Szrj   for (i = 0; i < D; i++)
393*a9fa9459Szrj     if (a[i] != NULL)
394*a9fa9459Szrj       {
395*a9fa9459Szrj 	fibheap_ins_root (heap, a[i]);
396*a9fa9459Szrj 	if (heap->min == NULL || fibheap_compare (heap, a[i], heap->min) < 0)
397*a9fa9459Szrj 	  heap->min = a[i];
398*a9fa9459Szrj       }
399*a9fa9459Szrj }
400*a9fa9459Szrj 
401*a9fa9459Szrj /* Make NODE a child of PARENT.  */
402*a9fa9459Szrj static void
fibheap_link(fibheap_t heap ATTRIBUTE_UNUSED,fibnode_t node,fibnode_t parent)403*a9fa9459Szrj fibheap_link (fibheap_t heap ATTRIBUTE_UNUSED,
404*a9fa9459Szrj               fibnode_t node, fibnode_t parent)
405*a9fa9459Szrj {
406*a9fa9459Szrj   if (parent->child == NULL)
407*a9fa9459Szrj     parent->child = node;
408*a9fa9459Szrj   else
409*a9fa9459Szrj     fibnode_insert_before (parent->child, node);
410*a9fa9459Szrj   node->parent = parent;
411*a9fa9459Szrj   parent->degree++;
412*a9fa9459Szrj   node->mark = 0;
413*a9fa9459Szrj }
414*a9fa9459Szrj 
415*a9fa9459Szrj /* Remove NODE from PARENT's child list.  */
416*a9fa9459Szrj static void
fibheap_cut(fibheap_t heap,fibnode_t node,fibnode_t parent)417*a9fa9459Szrj fibheap_cut (fibheap_t heap, fibnode_t node, fibnode_t parent)
418*a9fa9459Szrj {
419*a9fa9459Szrj   fibnode_remove (node);
420*a9fa9459Szrj   parent->degree--;
421*a9fa9459Szrj   fibheap_ins_root (heap, node);
422*a9fa9459Szrj   node->parent = NULL;
423*a9fa9459Szrj   node->mark = 0;
424*a9fa9459Szrj }
425*a9fa9459Szrj 
426*a9fa9459Szrj static void
fibheap_cascading_cut(fibheap_t heap,fibnode_t y)427*a9fa9459Szrj fibheap_cascading_cut (fibheap_t heap, fibnode_t y)
428*a9fa9459Szrj {
429*a9fa9459Szrj   fibnode_t z;
430*a9fa9459Szrj 
431*a9fa9459Szrj   while ((z = y->parent) != NULL)
432*a9fa9459Szrj     {
433*a9fa9459Szrj       if (y->mark == 0)
434*a9fa9459Szrj 	{
435*a9fa9459Szrj 	  y->mark = 1;
436*a9fa9459Szrj 	  return;
437*a9fa9459Szrj 	}
438*a9fa9459Szrj       else
439*a9fa9459Szrj 	{
440*a9fa9459Szrj 	  fibheap_cut (heap, y, z);
441*a9fa9459Szrj 	  y = z;
442*a9fa9459Szrj 	}
443*a9fa9459Szrj     }
444*a9fa9459Szrj }
445*a9fa9459Szrj 
446*a9fa9459Szrj static void
fibnode_insert_after(fibnode_t a,fibnode_t b)447*a9fa9459Szrj fibnode_insert_after (fibnode_t a, fibnode_t b)
448*a9fa9459Szrj {
449*a9fa9459Szrj   if (a == a->right)
450*a9fa9459Szrj     {
451*a9fa9459Szrj       a->right = b;
452*a9fa9459Szrj       a->left = b;
453*a9fa9459Szrj       b->right = a;
454*a9fa9459Szrj       b->left = a;
455*a9fa9459Szrj     }
456*a9fa9459Szrj   else
457*a9fa9459Szrj     {
458*a9fa9459Szrj       b->right = a->right;
459*a9fa9459Szrj       a->right->left = b;
460*a9fa9459Szrj       a->right = b;
461*a9fa9459Szrj       b->left = a;
462*a9fa9459Szrj     }
463*a9fa9459Szrj }
464*a9fa9459Szrj 
465*a9fa9459Szrj static fibnode_t
fibnode_remove(fibnode_t node)466*a9fa9459Szrj fibnode_remove (fibnode_t node)
467*a9fa9459Szrj {
468*a9fa9459Szrj   fibnode_t ret;
469*a9fa9459Szrj 
470*a9fa9459Szrj   if (node == node->left)
471*a9fa9459Szrj     ret = NULL;
472*a9fa9459Szrj   else
473*a9fa9459Szrj     ret = node->left;
474*a9fa9459Szrj 
475*a9fa9459Szrj   if (node->parent != NULL && node->parent->child == node)
476*a9fa9459Szrj     node->parent->child = ret;
477*a9fa9459Szrj 
478*a9fa9459Szrj   node->right->left = node->left;
479*a9fa9459Szrj   node->left->right = node->right;
480*a9fa9459Szrj 
481*a9fa9459Szrj   node->parent = NULL;
482*a9fa9459Szrj   node->left = node;
483*a9fa9459Szrj   node->right = node;
484*a9fa9459Szrj 
485*a9fa9459Szrj   return ret;
486*a9fa9459Szrj }
487