ADT - Binary Heap(二叉堆) &&
阿新 • • 發佈:2017-09-26
val break pre ide 代碼 opera function eas queue
今天早上起來完成了一個完整的基於二叉堆實現的優先隊列,其中包含最小優先和最大優先隊列。
實際上上篇也說了優先隊列的特性,通過建堆和堆排序操作,我們就已經看到了這種數據結構中的數據具有某種優先級別,要麽非根節點大於他的子節點,要麽就相反,在最大優先隊列中最大優先級別就是指節點值最大的數據為根節點,每次出隊時肯定是最大的先出去,反之則是最小優先隊列,但要註意插入時的數據不一定是最大或最小的,優先隊列會通過一點小技巧找到所有節點之間的關系並對應起來,重新使得你隨意插入的數據滿足優先隊列的特性,因而這種數據結構的使用很普遍。比如:操作系統中的任務調度等。
用線性表實現這種數據結構並不難,下面是優先隊列的代碼:
Head File:
1 #ifndef _PQ_H 2 #define _PQ_H 3 4 typedef struct 5 { 6 ElemType * arr; 7 int size; 8 }Heap; 9 10 Heap * Initialize_Heap(); 11 static int HeapParent(); 12 static int HeapLeft(); 13 static int HeapRight(); 14 static void Min_Heapify(); 15 static voidPriorityQueue.hMax_Heapify(); 16 void Build_Min_Heap(); 17 void Build_Max_Heap(); 18 void Heap_Sort(); 19 int Heap_Minimum(); 20 int Heap_Maximum(); 21 int Heap_Extract_Min(); 22 int Heap_Extract_Max(); 23 static void Heap_Increase_Min_Key(); 24 static void Heap_Increase_Max_Key(); 25 void Heap_Insert_Max();26 void Heap_Insert_Min(); 27 void Destroy_Heap(); 28 29 #endif
Operation Function:
1 #include <stdio.h> 2 #include "PriorityQueue.h" 3 4 /* 5 * 初始化堆 6 * 參數說明:無參數 7 * 8 * 返回堆 9 */ 10 Heap * Initialize_Heap(void) 11 { 12 Heap * heap; 13 14 heap = (Heap *)malloc(sizeof(Heap)); 15 heap -> arr = (ElemType *)malloc(sizeof(ElemType)); 16 heap -> size = -1; 17 18 return heap; 19 } 20 21 /* 22 * 節點i的雙親 23 */ 24 static int HeapParent(int i) 25 { 26 return i/2; 27 } 28 29 /* 30 * 節點i的左孩子 31 */ 32 static int HeapLeft(int i) 33 { 34 return 2*i + 1; 35 } 36 37 /* 38 * 節點i的右孩子 39 */ 40 static int HeapRight(int i) 41 { 42 return 2*(i + 1); 43 } 44 45 /* 46 * 維護最小堆的性質 47 */ 48 static void Min_Heapify(Heap * heap, int i) 49 { 50 int l = HeapLeft(i); 51 int r = HeapRight(i); 52 int smallest; 53 int temp; 54 55 if(l < heap -> size && heap -> arr[l] < heap -> arr[i]) 56 smallest = l; 57 else 58 smallest = i; 59 if(r < heap -> size && heap -> arr[r] < heap -> arr[i]) 60 smallest = r; 61 if(smallest != i) 62 { 63 temp = heap -> arr[i]; 64 heap -> arr[i] = heap -> arr[smallest]; 65 heap -> arr[smallest] = temp; 66 Min_Heapify(heap, smallest); 67 } 68 } 69 70 /* 71 * 維護最大堆的性質 72 */ 73 static void Max_Heapify(Heap * heap, int i) 74 { 75 int _L = HeapLeft(i); 76 int _R = HeapRight(i); 77 int largest; 78 int temp; 79 80 if(_L < heap -> size && heap -> arr[_L] > heap -> arr[i]) 81 largest = _L; 82 else 83 largest = i; 84 if(_R < heap -> size && heap -> arr[_R] > heap -> arr[largest]) 85 largest = _R; 86 if(largest != i) 87 { 88 temp = heap -> arr[i]; 89 heap -> arr[i] = heap -> arr[largest]; 90 heap -> arr[largest] = temp; 91 Max_Heapify(heap, largest); 92 } 93 } 94 95 /* 96 * 建最小堆 97 */ 98 void Build_Min_Heap(Heap * heap) 99 { 100 int i; 101 102 for(i = heap -> size/2; i >= 0; i--) 103 Min_Heapify(heap, i); 104 } 105 106 /* 107 * 建最大堆 108 */ 109 void Build_Max_Heap(Heap * heap) 110 { 111 int i; 112 113 for(i = heap -> size/2; i >= 0; i--) 114 Max_Heapify(heap, i); 115 } 116 117 /* 118 * 最大優先隊列 - 從小到大排序 119 */ 120 void Heap_Sort(Heap * heap) 121 { 122 int i; 123 int temp; 124 125 Build_Max_Heap(heap); 126 for(i = heap -> size; i >= 0; i--) 127 { 128 temp = heap -> arr[0]; 129 heap -> arr[0] = heap -> arr[i]; 130 heap -> arr[i] = temp; 131 -- heap -> size; 132 Max_Heapify(heap, 0); 133 } 134 } 135 136 /* 137 * 最小優先隊列 - 最小值 138 */ 139 int Heap_Minimum(Heap * heap) 140 { 141 return heap -> arr[0]; 142 } 143 144 /* 145 * 最大優先隊列 - 最大值 146 */ 147 int Heap_Maximum(Heap * heap) 148 { 149 return heap -> arr[0]; 150 } 151 152 /* 153 * 最小優先隊列 - 去除最小值節點 154 */ 155 int Heap_Extract_Min(Heap * heap) 156 { 157 int min; 158 159 if(heap -> size < 0) 160 { 161 fprintf(stderr, "Heap underflow!\n"); 162 return 0; 163 } 164 min = heap -> arr[0]; 165 heap -> arr[0] = heap -> arr[heap -> size]; 166 heap -> arr[heap -> size] = min; 167 -- heap -> size; 168 Min_Heapify(heap, 0); 169 170 return min; 171 } 172 173 /* 174 * 最大優先隊列 - 去除最大值節點 175 */ 176 int Heap_Extract_Max(Heap * heap) 177 { 178 int max; 179 180 if(heap -> size < 0) 181 { 182 fprintf(stderr, "Heap underflow!\n"); 183 return 0; //提前退出 184 } 185 max = heap -> arr[0]; 186 heap -> arr[0] = heap -> arr[heap -> size]; 187 -- heap -> size; 188 Max_Heapify(heap, 0); 189 190 return max; 191 } 192 193 /* 194 * 將key的值賦給節點i。此處將key值插入最小堆中 195 * 196 * 參數說明: 197 * 1.接收一個已存在的堆 198 * 2.節點位置 199 * 3.與堆節後數據相同類型的鍵值 200 */ 201 static void Heap_Increase_Min_Key(Heap * heap, int i, ElemType key) 202 { 203 int temp; 204 205 if(key > heap -> arr[i]) 206 { 207 printf("請輸入大於該而節點值的數據\n"); 208 return ; 209 } 210 heap -> arr[i] = key; 211 while(i > 0 && heap -> arr[HeapParent(i)] > heap -> arr[i]) 212 { 213 temp = heap -> arr[i]; 214 heap -> arr[i] = heap -> arr[HeapParent(i)]; 215 heap -> arr[HeapParent(i)] = temp; 216 i = HeapParent(i); 217 } 218 } 219 220 /* 221 * 將key的值賦給節點i。此處將key值插入最大堆中 222 * 223 * 參數說明: 224 * 1.接收一個已存在的堆 225 * 2.節點位置 226 * 3.與堆節後數據相同類型的鍵值 227 */ 228 static void Heap_Increase_Max_Key(Heap * heap, int i, ElemType key) 229 { 230 int temp; 231 232 if(key < heap -> arr[i]) 233 { 234 printf("請輸入大於該而節點值的數據\n"); 235 return ; 236 } 237 heap -> arr[i] = key; 238 while(i > 0 && heap -> arr[HeapParent(i)] < heap -> arr[i]) 239 { 240 temp = heap -> arr[i]; 241 heap -> arr[i] = heap -> arr[HeapParent(i)]; 242 heap -> arr[HeapParent(i)] = temp; 243 i = HeapParent(i); 244 } 245 } 246 247 /* 248 * 將key值插入最小堆 249 */ 250 void Heap_Insert_Min(Heap * heap, ElemType key) 251 { 252 ++ heap -> size; 253 heap -> arr[heap -> size] = -65533; 254 Heap_Increase_Min_Key(heap, heap -> size, key); 255 } 256 257 /* 258 * 將key值插入最大堆 259 */ 260 void Heap_Insert_Max(Heap * heap, ElemType key) 261 { 262 ++ heap -> size; 263 heap -> arr[heap -> size] = -65533; 264 Heap_Increase_Max_Key(heap, heap -> size, key); 265 } 266 267 /* 268 * 如果堆存在則銷毀堆 269 * 270 * 無參數/返回值 271 */ 272 void Destroy_Heap(Heap * heap) 273 { 274 if(heap && heap -> arr) 275 { 276 free(heap -> arr); 277 free(heap); 278 heap = NULL; 279 } 280 }PriorityQueue.c
test file:
1 #include <stdio.h> 2 #include <conio.h> 3 4 int main(void) 5 { 6 ElemType val; 7 Heap * heap; 8 char c; 9 int i, cont = 0; 10 11 heap = Initialize_Heap(); 12 13 puts("1) Insert Heap 2) Extract Max"); 14 puts("3) Display 4) Exit"); 15 16 while((c = getch()) != ‘4‘) 17 { 18 switch(c) 19 { 20 case ‘1‘ : cont ++; 21 printf("Enter key:"); 22 scanf("%d", &val); 23 Heap_Insert_Max(heap, val); 24 break; 25 case ‘2‘ : cont --; 26 printf("Max key = %d\n", Heap_Extract_Max(heap)); 27 break; 28 case ‘3‘ : Build_Max_Heap(heap); 29 printf("顯示數據:\n"); 30 for(i = 0; i < cont; i++) 31 printf("%d ", heap -> arr[i]); 32 printf("NULL\n"); 33 break; 34 } 35 } 36 // Destroy_Heap(); 37 38 return 0; 39 }test.c
ADT - Binary Heap(二叉堆) &&