This oblique heap does not detect xx. I didn't write it out because I didn't understand what the book meant. however, it seems to be a theoretically avoided 100% detection. or, at least, some facts verify the correctness of the Code.
Hope you can correct it!
/* Skew-heap.c-oblique heap implementation file */<br/> # include <stdio. h> <br/> # include <stdlib. h> <br/> # include "skew-heap.h" </P> <p>/* local ADT Declaration */</P> <p>/* Item1 is defined as the pointer type in illegal memory reference may occur after the original space is released */<br/>/* lessons learned: pointer should be used with caution. do not abuse node Item1 if you have no reason */<br/> typedef node Item1; <br/> typedef struct node1 <br/>{< br/> Item1 Item1; <br/> struct node1 * Next; <br/>} node1; <br/> typedef struct queue <br/>{< br/> node1 * front; <br/> node1 * rear; <br/> I NT size; <br/>}* queue; </P> <p> int initialize_queue (queue * const pqueue ); <br/> int queue_is_empty (const queue * const pqueue); <br/> int en_queue (const queue * const pqueue, const Item1 Item1 ); <br/> int de_queue (const queue * const pqueue, Item1 * const pitem1); <br/> void release _ (const queue * const pqueue ); <br/> node1 * make_node1 (const Item1 Item1); </P> <p>/* local function declaration */</P> <p> static H EAP merge1 (const heap H1, const heap H2); <br/> static heap swap_children (const heap H1 ); </P> <p>/* interface function definition */</P> <p> int create (heap * const pH) <br/>{< br/> * pH = (node *) malloc (sizeof (node); <br/> If (null = * pH) <br/> return 0; <br/> else <br/> {<br/> * pH = NULL; <br/> return 1; <br/>}</P> <p> int heapisempty (const heap h) <br/>{< br/> return null = h; <br/>}</P> <p> heap Merge (const H EAP H1, const heap H2) <br/>{< br/> If (null = h1) <br/> return H2; <br/> else if (null = h2) <br/> return H1; <br/> else if (H1-> item <H2-> item) <br/> return merge1 (H1, H2); <br/> else <br/> return merge1 (H2, H1 ); <br/>}</P> <p> heap insert (heap H, const item) <br/>{< br/> heap new_heap; </P> <p> new_heap = (node *) malloc (sizeof (node); <br/> If (null = new_heap) <br/> return h; <br/> Ne W_heap-> item = item; <br/> new_heap-> left = new_heap-> right = NULL; <br/> H = Merge (H, new_heap ); </P> <p> return h; <br/>}</P> <p> heap deletemin (heap H, node * const pnode) <br/> {<br/> node * temp; </P> <p> If (heapisempty (H) <br/> return h; <br/> temp = H; <br/> * pnode = * h; <br/> H = Merge (H-> left, H-> right ); <br/> free (temp); </P> <p> return h; <br/>}</P> <p> node * Find (const heap H, Const item) <br/>{< br/> node * temp; </P> <p> If (null = h) <br/> return NULL; <br/> else if (item = H-> item) <br/> return h; <br/> else if (temp = find (H-> left, ITEM) <br/> return temp; <br/> else if (temp = find (H-> right, item) <br/> return temp; <br/> else <br/> return NULL; <br/>}</P> <p> heap build (const item array [], const int size) <br/>{< br/> heap H1, H2; <br/> queue Q; <br /> Node * arr; <br/> int CT; </P> <p> If (! Initialize_queue (& Q) <br/> return NULL; <br/> arr = (node *) malloc (sizeof (node) * size ); <br/> for (Ct = 0; CT <size; CT ++) <br/> {<br/> arr [cT]. item = array [cT]; <br/> arr [cT]. left = arr [cT]. right = NULL; <br/> en_queue (& Q, arr [cT]); <br/>}< br/> // develops the habit of returning back immediately after memory is no longer used <br/> free (ARR ); <br/> while (Q-> size! = 1) <br/>{< br/> // memory allocation here, I only know that this memory is sufficient. it is unclear how the compiler allocates <br/> H1 = (node *) malloc (sizeof (node); <br/> H2 = (node *) malloc (sizeof (node); <br/> de_queue (& Q, H1); <br/> de_queue (& Q, H2 ); <br/> H1 = Merge (H1, H2); <br/> en_queue (& Q, * H1); <br/>}< br/> de_queue (& Q, h1); <br/> release _ (& Q ); <br/> // H1 and H2 jointly meet the demand for memory used by the inclined heap </P> <p> return H1; <br/>}</P> <p> void release (const heap h) <br/> {<br/> I F (h) <br/>{< br/> release (H-> left); <br/> release (H-> right ); <br/> free (h ); <br/>}</P> <p>/* local function definition */</P> <p> static heap merge1 (const heap H1, const heap H2) <br/>{< br/> If (null = h1-> left) <br/> H1-> left = h2; <br/> else <br/> {<br/> H1-> right = Merge (H1-> right, H2); <br/> // compared with the left-side heap, the advantage of oblique heap is that it saves space and reduces the number of condition checks <br/> swap_children (H1); <br/>}</P> <p> return H1; <br/>}</P> <p> stati C heap swap_children (const heap H1) <br/>{< br/> node * temp; </P> <p> temp = h1-> left; <br/> H1-> left = h1-> right; <br/> H1-> right = temp; </P> <p> return H1; <br/>}</P> <p>/* local ADT definition */</P> <p> int initialize_queue (queue * const pqueue) <br/>{< br/> * pqueue = (struct queue *) malloc (sizeof (struct queue); <br/> If (null = * pqueue) <br/> return 0; <br/> (* pqueue)-> front = (* pqueue)-> rear = NULL; <br/> (* pqueue)-> size = 0; </P> <p> return 1; <br/>}</P> <p> int queue_is_empty (const queue * const pqueue) <br/>{< br/> return 0 = (* pqueue) -> size; <br/>}</P> <p> int en_queue (const queue * const pqueue, const Item1 Item1) <br/>{< br/> node1 * new_node; </P> <p> new_node = make_node1 (Item1); <br/> If (null = new_node) <br/> return 0; <br/> If (queue_is_empty (pqueue) <br/>{< br/> // The queue actually passes Front implementation, rear only plays a secondary role. therefore, do not allocate space for it <br/> (* pqueue)-> front = (* pqueue)-> rear = new_node; <br/>}< br/> else <br/> {<br/>/* maybe I have understood the meaning of this Code till now */<br/> /* in the second call, (* pqueue)-> rear-> next = new_node is actually equivalent to (* pqueue) -> front-> next = new_node */<br/>/* completes the queue connection in this step. too implicit. I used to seem confused! */<Br/> (* pqueue)-> rear-> next = new_node; <br/> (* pqueue)-> rear = new_node; <br/>}< br/> (* pqueue)-> size ++; </P> <p> return 1; <br/>}</P> <p> int de_queue (const queue * const pqueue, Item1 * const pitem1) <br/>{< br/> node1 * temp; </P> <p> If (queue_is_empty (pqueue) <br/> return 0; <br/> * pitem1 = (* pqueue)-> front-> Item1; <br/> temp = (* pqueue)-> front; <br/> If (* pqueue)-> size! = 1) <br/> (* pqueue)-> front = (* pqueue)-> front-> next; <br/> else <br/> (* pqueue) -> front = (* pqueue)-> rear = NULL; <br/> (* pqueue)-> size --; <br/> free (temp ); </P> <p> return 1; <br/>}</P> <p> void release _ (const queue * const pqueue) <br/>{< br/> node1 * scan, * temp; </P> <p> scan = (* pqueue)-> front; <br/> while (SCAN) <br/> {<br/> temp = scan; <br/> scan = scan-> next; <br/> free (temp); <br/>}< br/> free (* pqueue ); <br/>}</P> <p> node1 * make_node1 (const Item1 Item1) <br/>{< br/> node1 * new_node; </P> <p> new_node = (node1 *) malloc (sizeof (node1); <br/> If (null = new_node) <br/> return NULL; <br/> new_node-> Item1 = Item1; <br/> new_node-> next = NULL; </P> <p> return new_node; <br/>}