1 // 优先队列 Heap
2 // 前缀: Heap
3
4 #ifndef _HEAP_H
5 #define _HEAP_H
6
7 #define HEAP_DEFAULT_CAPACITY 10
8 typedef int Rank;
9 typedef int HeapT;
10 typedef struct {
11 int Capacity; // 容量
12 int Size; // 元素个数
13 HeapT *Elems;
14 } HeapNode;
15 typedef HeapNode *Heap;
16
17 Heap Heap_Create( int Capa );
18 void Heap_Destroy( Heap *Pheap );
19 void Heap_Insert( Heap H, HeapT E );
20 HeapT Heap_DeleteMin( Heap H );
21 int Heap_IsFull( Heap H );
22 int Heap_IsEmpty( Heap H );
23
24 // test
25 void Heap_TestPrint(Heap H);
26
27 #endif /* _HEAP_H */

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "heap.h"
4
5 Heap Heap_Create(int Capa)
6 {
7 if(Capa < HEAP_DEFAULT_CAPACITY) {
8 Capa = HEAP_DEFAULT_CAPACITY;
9 }
10 Heap heap = (Heap)malloc(sizeof(HeapNode));
11 if(heap == NULL) {
12 printf("Out of space!!\n");
13 return NULL;
14 }
15 heap->Capacity = Capa + 1; // 数组0下标处不放数据
16 heap->Size = 0;
17 heap->Elems = (HeapT *)malloc(sizeof(HeapT) * (heap->Capacity));
18 if(heap->Elems == NULL) {
19 free(heap);
20 printf("Out of space!!\n");
21 return NULL;
22 }
23 return heap;
24 }
25
26 void Heap_Destroy(Heap *Pheap)
27 {
28 if(Pheap != NULL && *Pheap != NULL) {
29 Heap heap = *Pheap;
30 free(heap->Elems);
31 free(heap);
32 *Pheap = NULL;
33 }
34 }
35
36 void Heap_Insert(Heap H, HeapT E)
37 {
38 if(H == NULL) return ;
39 if( Heap_IsFull(H) ) {
40 printf("Heap is Full!!\n");
41 return ;
42 }
43
44 Rank cell = ++(H->Size);
45 while(cell > 1) {
46 Rank parent = cell / 2;
47 if( H->Elems[parent] < E ) { // 找到插入位置
48 break;
49 } else { // 未找到位置,上滤
50 H->Elems[cell] = H->Elems[parent];
51 cell = parent;
52 }
53 }
54 // cell位置,要么是根节点(1),要么是插入值小于cell父亲的值
55 H->Elems[cell] = E;
56 }
57
58 HeapT Heap_DeleteMin(Heap H)
59 {
60 if(H == NULL) return ;
61 if( Heap_IsEmpty(H) ) {
62 printf("Heap is Empty!!\n");
63 return ;
64 }
65
66 HeapT result = H->Elems[1];
67 HeapT LastElem = H->Elems[H->Size];
68 H->Size--;
69 Rank cell = 1; // LastElem位置
70 while(2 * cell <= H->Size) { // 当cell左孩子(2 * cell)存在,即cell不是叶子节点
71 Rank lchild = 2 * cell, rchild = 2 * cell + 1;
72 Rank minchild = lchild;
73 if( rchild <= H->Size && H->Elems[rchild] < H->Elems[lchild] ) { // 如果右孩子存在
74 minchild = rchild;
75 }
76
77 // 若cell左右孩子中较小的都大于等于LastElem,则cell为LastElem位置
78 if( H->Elems[minchild] >= LastElem ) {
79 break;
80 } else { // 下滤
81 H->Elems[cell] = H->Elems[minchild];
82 cell = minchild;
83 }
84 }
85 // cell的位置,要么是叶子节点,要么是cell左右孩子值均小于LastElem
86 H->Elems[cell] = LastElem;
87 return result;
88 }
89
90 int Heap_IsEmpty(Heap H)
91 {
92 return H != NULL && H->Size == 0 ? 1 : 0;
93 }
94
95 int Heap_IsFull(Heap H)
96 {
97 return H != NULL && H->Size + 1 == H->Capacity ? 1 : 0;
98 }
99
100 void Heap_TestPrint(Heap H)
101 {
102 if(H == NULL) {
103 printf("Heap is NULL.\n");
104 return ;
105 }
106 for(int i = 1; i < H->Size + 1; i++) {
107 printf("%d ", H->Elems[i]);
108 }
109 printf("\n");
110 printf("Size: %d, Capa: %d\n", H->Size, H->Capacity);
111 }
heap.c