/* Binomial-queue.c-two queue implementation files */<br/> # include "binomial-queue.h" </P> <p>/* local function declaration */</P> <p>> static subtree combine_trees (subtree T1, subtree T2); <br/> static node * make_node (const item); <br/> static void recursively (const subtree T, void (* pfun) (const item); </P> <p>/* interface function definition */</P> <p> int initializebinqueue (binqueue * const PBq, const int size) <br/>{< br/> int I; </P> <p> If (size <= 0) <Br/> return 0; <br/> * PBq = (struct binqueue *) malloc (sizeof (struct binqueue); <br/> If (null = * PBq) <br/> return 0; <br/> (* PBq)-> forest = (subtree *) malloc (sizeof (subtree) * size ); <br/> If (null = (* PBq)-> forest) <br/>{< br/> free (* PBq); <br/> return 0; <br/>}< br/> for (I = 0; I <size; I ++) <br/> (* PBq)-> forest [I] = NULL; <br/> (* PBq)-> size = size; <br/> (* PBq)-> current = 0; </P> <p> return 1; <br/>}</P> <p> int binqueueisempty (const binqueue Bq) <br/>{< br/> return 0 = BQ-> current; <br/>}</P> <p> binqueue Merge (binqueue bq1, binqueue bq2) <br/> {<br/> binqueue temp; <br/> subtree T1, T2, carry = NULL; <br/> int I, j, CT, Index = 0; </P> <p> // The detection here is very important. <br/> If (bq1 = bq2) <br/> return bq1; <br/> If (bq1-> current + bq2-> current> bq1-> size) <br/> return bq1; <br /> Bq1-> current + = bq2-> current; <br/> // bq1-> current> bq2-> current --> <br/> If (bq1-> current <bq2-> current) <br/>{< br/> temp = bq1; <br/> bq1 = bq2; <br/> bq2 = temp; <br/>}< br/> // this way, you can use the condition detection that all the subtree of bq2 has been merged. <br/> // when bq2-> when current is very small, it will cause too many unnecessary condition checks --> <br/> for (I = 0, j = 1, Ct = 0; j <= bq1-> current; I ++, J * = 2) <br/>{< br/> T1 = bq1-> forest [I]; <br/> // The following judgment is For insert, because I only allocated space for one subtree during insert <br/> if (1 = index) <br/> T2 = NULL; <br/> else if (1 = bq2-> size) <br/> {<br/> Index = 1; <br/> T2 = bq2-> forest [I]; <br/>}< br/> else <br/> T2 = bq2-> forest [I]; <br/> // This method is really clever, open your eyes <br/> switch (!! T1 + 2 *!! T2 + 4 *!! Carry) <br/> {<br/> // no trees <br/> case 0: break; <br/> // only bq1 <br/> case 1: if (Ct = bq2-> size) <br/>{< br/> release (bq2); <br/> return bq1; <br/>}< br/> break; <br/> // only bq2 <br/> case 2: bq1-> forest [I] = t2; <br/> bq2-> forest [I] = NULL; <br/> CT ++; <br/> break; <br/> // only carry <br/> case 4: bq1-> forest [I] = carry; <br/> carry = NULL; <br/> break; <br/> // bq1 and bq2 <br/> case 3: Carry = combine_trees (T1, T2); <br/> bq1-> forest [I] = bq2-> forest [I] = NULL; <br/> CT ++; <br/> break; <br/> // bq1 and carry <br/> case 5: Carry = combine_trees (T1, carry ); <br/> bq1-> forest [I] = NULL; <br/> break; <br/> // bq2 and carry <br/> case 6: carry = combine_trees (t2, carry); <br/> bq2-> forest [I] = NULL; <br/> CT ++; <br/> break; <br/> // All there <br/> case 7: bq1-> forest [I] = car Ry; <br/> carry = combine_trees (T1, T2); <br/> bq2-> forest [I] = NULL; <br/> break; <br/>}</P> <p> return bq1; <br/>}</P> <p> binqueue insert (binqueue Bq, const item) <br/>{< br/> binqueue temp; <br/> int size = 1; </P> <p> If (BQ-> size = BQ-> current) <br/> return BQ; <br/> If (! Initializebinqueue (& temp, size) <br/>{< br/> free (temp-> forest); <br/> free (temp ); <br/> return BQ; <br/>}< br/> temp-> forest [0] = make_node (item ); <br/> If (null = temp-> forest [0]) // the original "; "<br/>{< br/> free (temp-> forest [0]); <br/> free (temp); <br/> return BQ; <br/>}< br/> temp-> current = 1; <br/> BQ = Merge (Bq, temp); </P> <p> return BQ; <br/>}</P> <p> item deletemin (binqueue Bq) <br/>{< br/> binqueue deleted_queue; <br/> subtree deleted_tree, old_root; <br/> item min; <br/> int I, j, size, min_index; </P> <p> If (binqueueisempty (Bq )) <br/> return-infinity; <br/> min = infinity; <br/> for (I = 0, size = BQ-> size; I <size; I ++) <br/>{< br/> If (BQ-> forest [I] & BQ-> forest [I]-> item <min) <br/>{< br/> min = BQ-> forest [I]-> item; <br/> min_index = I; <br/>}< br/> If (infinity = min) <br/> return infinity; <br/> deleted_tree = BQ-> forest [min_index]; <br/> old_root = deleted_tree; <br/> deleted_tree = deleted_tree-> left; <br/> free (old_root); <br/> initializebinqueue (& deleted_queue, (1 <min_index)-1); <br/> for (j = min_index-1; j> = 0; j --) <br/>{< br/> deleted_queue-> forest [J] = deleted_tree; <br/> deleted_tree = deleted_tree-> nextsibling; <br/> deleted_queue-> forest [J]-> nextsibling = NULL; <br/>}< br/> BQ-> forest [min_index] = NULL; <br/> BQ-> current-= deleted_queue-> current + 1; </P> <p> BQ = Merge (Bq, deleted_queue ); </P> <p> return min; <br/>}</P> <p> void traversal (const binqueue Bq, void (* pfun) (const item )) <br/>{< br/> int I, size; </P> <p> for (I = 0, size = BQ-> size; I <size; I ++) <br/> If (BQ-> forest [I]) <br/> recursively (BQ-> forest [I], pfun ); <br/>}</P> <p> void release (const binqueue Bq) <br/>{< br/> int I, size; </P> <p> for (I = 0, size = BQ-> size; I <size; I ++) <br/>{< br/> If (BQ-> forest [I]) <br/> free (BQ-> forest [I]); <br/>}< br/> free (Bq ); <br/>}</P> <p>/* local function definition */</P> <p> static subtree combine_trees (subtree T1, subtree T2) <br/>{< br/> If (T1-> item> T2-> item) <br/> return combine_trees (t2, T1 ); // T1. I don't know what I was thinking this day. <br/> T2-> nextsibling = T1-> left; <br/> T1-> left = t2; </P> <p> return T1; <br/>}</P> <p> static node * make_node (const item) <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 = item; <br/> new_node-> left = new_node-> nextsibling = NULL; </P> <p> return new_node; <br/>}</P> <p> static void recursively (const subtree T, void (* pfun) (const item )) <br/>{< br/> If (t-> left) <br/> recursively (t-> left, pfun ); <br/> If (t-> nextsibling) <br/> recursively (t-> nextsibling, pfun); <br/> (* pfun) (t-> item ); <br/>}