如下图:


从 last_child/2 节点往前,每个节点与其子节点比较,按照 fixDown 操作,如下图:

执行 delMax 操作,将最大值输出,然后将最后的节点编程根节点,然后执行 fixDown 操作,如下图:


参考:HEAP SORT
代码实现如下:
pq.h
// pq.h: ADT interface for a priority queue #include <stdio.h> #include <stdlib.h> typedef struct pqRep *PQ; PQ createPQ(int size); void insertPQ(PQ q, int it); int delMaxPQ(PQ q); int isEmptyPQ(PQ q);
pqSort.c
/* pqSort.c: use a priority queue to sort an array of integers
into descending order
*/
#include "pq.h"
int main() {
int a[] = {41, 2, 58, 156, 360, 81, 260, 74, 167, 13};
int length = sizeof(a)/sizeof(a[0]);
PQ q = createPQ(length);
printf("Array: ");
for (int i = 0; i < length; i++) {
printf("%d ", a[i]);
insertPQ(q, a[i]);
}
printf("\nSorted: ");
while (!isEmptyPQ(q)) {
printf("%d ", delMaxPQ(q));
}
putchar(‘\n‘);
return EXIT_SUCCESS;
}
pqHP.c
// pqHP.c: priority queue implementation for pq.h using a heap
#include "pq.h"
// ‘static‘ means these functions are for local use only
static void fixDown(int *, int, int);
static void fixUp(int *, int);
// Priority queue implementation using an unordered array
struct pqRep {
int nItems; // actual count of Items
int *items; // array of Items
int maxsize; // maximum size of array
};
PQ createPQ(int size) {
PQ q = malloc(sizeof(struct pqRep)); // make room for the structure
if (q == NULL) {
fprintf(stderr, "out of memory\n");
exit(0);
}
q->items = malloc((size+1) * sizeof(int)); // make room for the array
if (q->items == NULL) { // size+1 because heap 1..size
fprintf(stderr, "out of memory\n");
exit(0);
}
q->nItems = 0; // we have no items yet
q->maxsize = size; // remember the maxsize
return q; // return the initial PQ
}
void insertPQ(PQ q, int it) {
if (q == NULL) {
fprintf(stderr, "priority queue not initialised\n");
exit(1);
}
if (q->nItems == q->maxsize) {
fprintf(stderr, "priority queue full\n");
exit(1);
}
q->nItems++; // adding another item
q->items[q->nItems] = it; // put the item at the end
fixUp(q->items, q->nItems); // fixUp all the way to the root
return;
}
int delMaxPQ(PQ q) {
if (q == NULL) {
fprintf(stderr, "priority queue not initialised\n");
exit(1);
}
if (q->nItems == 0) {
fprintf(stderr, "priority queue empty\n");
exit(1);
}
int retval = q->items[1]; // this is the item we want to return
q->items[1] = q->items[q->nItems]; // overwrite root by last item
q->nItems--; // we are decreasing heap size by 1
fixDown(q->items, 1, q->nItems); // fixDown the new root
return retval;
}
int isEmptyPQ(PQ q) {
int empty = 0;
if (q == NULL) {
fprintf(stderr, "isEmptyPQ: priority queue not initialised\n");
}
else {
empty = q->nItems == 0;
}
return empty;
}
// fix up the heap for the ‘new‘ element child
void fixUp(int *heap, int child) {
while (child>1 && heap[child/2]<heap[child]) {
int swap = heap[child]; // if parent < child, do a swap
heap[child] = heap[child/2];
heap[child/2] = swap;
child = child/2; // become the parent
}
return;
}
// force value at a[par] into correct position
void fixDown(int *heap, int par, int len) {
int finished = 0;
while (2*par<=len && !finished) {// as long as you are within bounds
int child = 2*par; // the first child is here
if (child<len && heap[child]<heap[child+1]) {
child++; // choose larger of two children
}
if (heap[par]<heap[child]) { // if node is smaller than this child ...
int swap = heap[child]; // if parent < child, do a swap
heap[child] = heap[child/2];
heap[child/2] = swap;
par = child; // ... and become this child
}
else {
finished = 1; // else we do not have to go any further
}
}
return;
}
Compile and run:
prompt$ dcc pqHP.c pqSort.c prompt$ ./a.out Array: 41 2 58 156 360 81 260 74 167 13 Sorted: 360 260 167 156 81 74 58 41 13 2
原文:https://www.cnblogs.com/alex-bn-lee/p/11175430.html