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 }