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