/* Fibonacciheap. C -- implementation file of the Fibonacci heap */<br/> # include "fibonacciheap. H "</P> <p>/* local function declaration */</P> <p> static node * makenode (const item * const PI ); <br/> static int logbaseontwo (const int current); <br/> static void Link (node * List, node * const new_node ); <br/> static void cut (node * const gap); <br/> static void Merge (node * const root, node * const child ); <br/> static void findcascadingcutandrenew (No De * const Pn, node * const list); <br/> static void renewdegree (node * const parent, const int degree ); <br/> static void release (node * const PN ); </P> <p>/* interface function definition */</P> <p> bool initialize_f (fibonacciheap * const PFH) <br/>{< br/> * PFH = (struct fibonacciheap *) malloc (sizeof (struct fibonacciheap); <br/> If (null = * PFH) <br/> return false; <br/> (* PFH)-> min = NULL; <br/> (* PFH)-> current = 0; </P> <p> return true; <br/>}</P> <p> bool isempty_f (const fibonacciheap * const PFH) <br/>{< br/> If (0 = (* PFH)-> current) <br/> return true; <br/> else <br/> return false; <br/>}</P> <p> bool insert_f (const fibonacciheap * const PFH, const item * const PI) <br/>{< br/> node * new_node; </P> <p> new_node = makenode (PI); <br/> If (null = new_node) <br/> return false; <br/> If (isempty_f (PFH) <br /> (* PFH)-> min = new_node; <br/> else <br/> {<br/> Link (* PFH)-> min, new_node ); <br/> If (new_node-> item <(* PFH)-> Min-> item) <br/> (* PFH)-> min = new_node; <br/>}< br/> (* PFH)-> current ++; </P> <p> return true; <br/>}</P> <p> item deletemin_f (const fibonacciheap * const PFH) <br/>{< br/> node ** assistant, * temp; <br/> node * scan, * record; <br/> item return_value; <br/> int size, I; </ P> <p> If (isempty_f (PFH) <br/> return empty; <br/>/* record the return value. */<br/> return_value = (* PFH)-> Min-> item; <br/>/* if there is only one node in the heap. */<br/> if (1 = (* PFH)-> current) <br/>{< br/> free (* PFH)-> min ); <br/> (* PFH)-> min = NULL; <br/>}< br/> else <br/> {<br/>/* if it has one child at least. */<br/> If (* PFH)-> Min-> child! = NULL) <br/>{< br/> scan = (* PFH)-> Min-> child; <br/> DO <br/> {<br/> (* PFH)-> Min-> degree-= scan-> degree; <br/> temp = scan-> right; <br/> scan-> parent = NULL; <br/> Link (* PFH)-> min, scan ); <br/> scan = temp; <br/>}< br/> while (* PFH)-> Min-> degree> 1) <br/>; <br/>/* Min-> child will be null for sure. */<br/> (* PFH)-> Min-> child = NULL; <br/>}< br/>/* if it has no child, only Do these. */<br/> temp = (* PFH)-> min; <br/>/* Find a new min, it can be any point. */<br/> (* PFH)-> min = (* PFH)-> Min-> right; <br/>/* Delete Min. */<br/> cut (temp); <br/> free (temp); <br/>/* find the real Min. */<br/>/* It is O (n ). */<br/> scan = record = (* PFH)-> min; <br/> DO <br/> {<br/> If (scan-> right-> item <(* PFH)-> Min-> item) <br/> (* PFH)-> min = scan-> right; <br/> scan = SC An-> right; <br/>}< br/> while (scan! = Record) <br/>; <br/>/* allocate memory space for the assistant list. */<br/> size = logbaseontwo (* PFH)-> current-1); <br/> assistant = (node **) malloc (sizeof (node *) * size); <br/> If (null = Assistant) <br/> {<br/> printf ("faild in/" If (null = Assistant) /""); <br/> return empty; <br/>}< br/> for (I = 0; I <size; I ++) <br/> assistant [I] = NULL; <br/>/* merge. */<br/> scan = record = (* pf H)-> min; <br/> for (I = 0; I <size; I ++) <br/> {<br/> DO <br/> {<br/> temp = scan-> right; <br/>/* as an example, logbaseontwo (5) = logbaseontwo (8) = 3, they two will be merged. */<br/> if (I = logbaseontwo (scan-> degree) <br/>{< br/> If (null = Assistant [I]) <br/> assistant [I] = scan; <br/> else <br/> {<br/> temp = scan-> right; <br/> If (scan-> item <assistant [I]-> item) <br/>{< br/> cut (Assistant [I]); <br/> Merge (scan, assistant [I]); <br/>}< br/> else <br/> {<br/> cut (SCAN); <br/> Merge (Assistant [I], scan ); <br/>}< br/> assistant [I] = NULL; <br/>}< br/> scan = temp; <br/>}< br/> while (scan! = Record) <br/>; <br/>}< br/> free (Assistant); <br/>}</P> <p> (* PFH) -> current --; </P> <p> return return_value; <br/>}</P> <p>/* please make sure that PN is in * PFH before you use this function. */<br/> bool decreasekey_f (const fibonacciheap * const PFH, node * const Pn, const int delta) <br/> {<br/> node * parent; </P> <p> If (isempty_f (PFH) <br/> return false; <br/> assert (PN! = NULL); <br/> assert (delta> 0); <br/> PN-> item-= delta; <br/> If (PN-> parent! = NULL & PN-> item <PN-> parent-> item) <br/>{< br/> parent = Pn-> parent; <br/> renewdegree (parent, PN-> degree); <br/> If (PN-> left = Pn) <br/> parent-> child = NULL; <br/> else <br/>{< br/> parent-> child = Pn-> right; <br/> cut (PN ); <br/>}< br/> PN-> parent = NULL; <br/> If (true = Pn-> index) <br/> PN-> Index = false; <br/> Link (* PFH)-> min, PN ); <br/> If (true = parent-> I Ndex) <br/> findcascadingcutandrenew (parent, (* PFH)-> min); <br/> else <br/> parent-> Index = true; <br/>}< br/> If (PN-> item <(* PFH)-> Min-> item) <br/> (* PFH) -> min = pN; </P> <p> return true; <br/>}</P> <p> bool delete_f (const fibonacciheap * const PFH, node * const PN) <br/> {<br/> If (isempty_f (PFH) <br/> return false; <br/>/* For avert overflow, negative_infinty is not the smallest numbe R in 32 bits. */<br/> decreasekey_f (PFH, Pn, negative_infinty); <br/> deletemin_f (PFH); </P> <p> return true; <br/>}</P> <p> void release_f (const fibonacciheap * const PFH) <br/>{< br/> If (* PFH)-> Min! = NULL) <br/> release (* PFH)-> min); <br/> free (* PFH ); <br/>}</P> <p>/* local function definition */</P> <p> static node * makenode (const item * const PI) <br/> {<br/> node * new_node; </P> <p> new_node = (node *) malloc (sizeof (node )); <br/> If (null = new_node) <br/> return NULL; <br/> new_node-> item = * PI; <br/> new_node-> degree = 1; <br/> new_node-> Index = false; <br/> new_node-> left = new_node-> right = ne W_node; <br/> new_node-> parent = new_node-> child = NULL; </P> <p> return new_node; <br/>}</P> <p> static int logbaseontwo (const int current) <br/>{< br/> int power, value; </P> <p> for (value = 1, power = 0; value <Current; power ++) <br/> value <= 1; </P> <p> return power; <br/>}</P> <p>/* can't process if list is empty. */<br/> static void Link (node * List, node * const new_node) <br/> {<br/>/* If th Ere is only one node in list. */<br/> If (list = List-> right) <br/> {<br/> list-> left = List-> right = new_node; <br/> new_node-> left = new_node-> right = List; <br/>}< br/> else <br/>{< br/> list-> right-> left = new_node; <br/> new_node-> left = List; <br/> new_node-> right = List-> right; <br/> list-> right = new_node; <br/>}</P> <p> static void cut (node * const gap) <br/> {<B R/> gap-> left-> right = gap-> right; <br/> gap-> right-> left = gap-> left; <br/>}</P> <p> static void Merge (node * const root, node * const child) <br/>{< br/> child-> parent = root; <br/> root-> degree + = Child-> degree; <br/> If (null = root-> child) <br/>{< br/> child-> left = Child-> right = child; <br/> root-> child = Child; <br/>}< br/> else <br/> Link (root-> child, child); <B R/>}</P> <p> static void findcascadingcutandrenew (node * const Pn, node * const List) <br/>{< br/> node * parent = Pn-> parent; </P> <p> If (parent! = NULL) <br/>{< br/> renewdegree (parent, PN-> degree); <br/> if (1 = Pn-> degree) <br/> parent-> child = NULL; <br/> else <br/> {<br/> parent-> child = Pn-> right; <br/> cut (PN); <br/>}< br/> PN-> parent = NULL; <br/> Link (list, PN ); <br/> If (true = parent-> index) <br/> findcascadingcutandrenew (parent, list ); <br/> else <br/> parent-> Index = true; <br/>}</P> <p> static void renewd Egree (node * const parent, const int degree) <br/>{< br/> assert (parent! = NULL); <br/> parent-> degree-= degree; <br/> If (parent-> parent! = NULL) <br/> renewdegree (parent-> parent, degree); <br/>}</P> <p>/* It is so skilful! I am a talent! */<Br/> static void release (node * const PN) <br/>{< br/> If (PN-> child! = NULL) <br/> release (PN-> child); <br/> If (PN! = Pn-> Right & PN-> right-> item! = Be_released) <br/>{< br/> PN-> item = be_released; <br/> release (PN-> right ); <br/>}< br/> free (PN); <br/>}