# Include "expandinglist. H"
/* Implement a heap-Sort */
/*
Create a heap.
Heapcreate (heaplist heapvar,
(Typename) heaptype,
Int initialsize,
INT (* compare_fn) (const void * a, const void * B ))
Add an item to the heap.
Heapadd (heaplist heapvar,
(Typename) heaptype,
Heaptype item)
Return the value of an item in the heap.
Heapitem (heaplist heapvar,
(Typename) heaptype,
Heaptype X)
Return the size of the heap.
Heapsize (heaplist heapvar,
(Typename) heaptype)
Return the top item on the heap. (As modifiable lvalue)
Heaptop (heaplist heapvar,
(Typename) heaptype)
Remove the top item from the heap, assign it to itemvar.
Heappop (heaplist heapvar,
(Typename) heaptype,
Heaptype itemvar)
Destroy a heap with or without data in it.
Heapdestroy (heaplist heapvar,
(Typename) heaptype)
*/
/*
The heapsort algorithm works well when adding data to a list
In random order, and removing it in a sorted order. Worst-case
Performance is O (n log (n )).
As items are added, they are kept in a min-heap. A Min-heap
Is a binary tree in which every parent is less than either of its
Children. It will always be full, so it can be implemented
A simple array. Like such:
A [] = {2, 5, 3, 13, 11, 17, 7}
-Or-
2
//
5 3
////
13 11 17 7
When an item is added, it is stuck at the end of the tree and
Floated up until is less than its parent.
2
//
5 3
////
13 11 17 7
/
4
-4 floats up-
2
//
5 3
////
4 11 17 7
/
13
2
//
4 3
////
5 11 17 7
/
13
When pulling items off the list in sorted order, pull off the top
Node first, replace it with the last node, and have the new top node
Sink down until it is less than either of its children. Make sure,
When swapping it with a child, to swap it with the lesser child.
2 <--
//
4 3
////
5 11 17 7
/
13
13
//
4 3
////
5 11 17 7
3
//
4 13
////
5 11 17 7
3
//
4 7
////
5 11 17 13
Do this until the tree is empty.
*/
# Ifndef heapsort_h
# Define heapsort_h
# Define heapsort_parent _ (x) = 0 )? -1: (x)-1)/2 ))
# Define heapsort_lchild _ (x) + 1) * 2-1)
# Define heapsort_rchild _ (x) + 1) * 2)
# Ifdef _ stdc __
# Define heapsort_compare _ (heapvar, type, A, B )/
(* (INT (*) (type *, type *) (heapvar)-> compare) (a, B ))
# Else
# Define heapsort_compare _ (heapvar, type, A, B )/
(* (Heapvar)-> compare) (a, B ))
# Endif
Struct heaplist _{
Xpandlist list;
INT (* compare )();
};
Typedef struct heaplist _ * heaplist;
# Define heapcreate (heapvar, type, initialsize, compare_fn) do {/
(Heapvar) = (heaplist) malloc (sizeof (struct heaplist _));/
If (! (Heapvar )){/
Fprintf (stderr, "cocould not allocate memory for Min-heap/N ");/
} Else {/
Listcreate (heapvar)-> list, type, (initialsize ));/
If (heapvar)-> List ){/
(Heapvar)-> compare = (INT (*) (compare_fn );/
}/
}/
} While (0)
# Define heapdestroy (heapvar, type) do {/
Listdestroy (heapvar), type );/
Free (char *) (heapvar);} while (0)
# Define heapadd (heapvar, type, item) do {/
Int _ I ;/
Type * _ head ;/
Type _ x ;/
_ Head = listheadptr (heapvar)-> list, type );/
/* Make room in the list *//
Listadditem (heapvar)-> list, type, (item ));/
_ X = (item );/
/* Float the new item up to the top *//
_ I = listsize (heapvar)-> list, type)-1 ;/
While (_ I & heapsort_compare _ (heapvar, type ,/
(_ Head) + heapsort_parent _ (_ I ),/
& _ X)> 0 ){/
* (_ Head + _ I) = * (_ head + heapsort_parent _ (_ I ));/
_ I = heapsort_parent _ (_ I );/
}/
* (_ Head + _ I) = _ x ;/
} While (0)
# Define heapitem (heapvar, type, I )/
Listitem (heapvar)-> list, type, (I ))
# Define heapsize (heapvar, type )/
Listsize (heapvar)-> list, type)
# Define heaptop (heapvar, type )/
Listitem (heapvar)-> list, type, 0)
# Define heappop (heapvar, type, itemvar) do {/
Int _ I, _ size ;/
Type * _ head ;/
Type _ x ;/
/
/* Get the top item *//
(Itemvar) = listitem (heapvar)-> list, type, 0 );/
/* Grab the last item *//
_ X = listitem (heapvar)-> list, type ,/
Listsize (heapvar)-> list, type)-1 );/
Listremoveitems (heapvar)-> list, type, 1 );/
/
_ I = 0 ;/
_ Size = heapsize (heapvar, type );/
_ Head = listheadptr (heapvar)-> list, type );/
/
/* If I haven't sunk past the end of the heap ,/
And one of our chilren outweighs me *//
While (heapsort_lchild _ (_ I) <_ SIZE ){/
If (heapsort_rchild _ (_ I)> = _ SIZE ){/
/
/* Only have left child, no right child *//
If (heapsort_compare _ (heapvar, type ,/
& _ X, _ head + heapsort_lchild _ (_ I)> 0 ){/
/* If greater than this one child, move the child up/
And set I so that X gets put in this child's place *//
* (_ Head + _ I) = * (_ head + heapsort_lchild _ (_ I ));/
_ I = heapsort_lchild _ (_ I );/
} Else {/
/* If less than this one child, we're home! Leave I where it is/
And exit so that X gets written *//
Break ;/
}/
} Else {/
/* Have both children *//
If (heapsort_compare _ (heapvar, type ,/
_ Head + heapsort_lchild _ (_ I), & _ x)> 0 &&/
Heapsort_compare _ (heapvar, type ,/
_ Head + heapsort_rchild _ (_ I), & _ x)> 0 ){/
/* If both children are greater than X, we're home *//
Break ;/
} Else {/
/* Swap with the smaller of the Children *//
If (heapsort_compare _ (heapvar, type ,/
_ Head + heapsort_lchild _ (_ I), _ head + heapsort_rchild _ (_ I) <0 ){/
* (_ Head + _ I) = * (_ head + heapsort_lchild _ (_ I ));/
_ I = heapsort_lchild _ (_ I );/
} Else {/
* (_ Head + _ I) = * (_ head + heapsort_rchild _ (_ I ));/
_ I = heapsort_rchild _ (_ I );/
}/
}/
}/
}/
/
/* Put X in its rightful place *//
* (_ Head + _ I) = _ x ;/
} While (0)
# Endif