用大根堆實現大值優先佇列
阿新 • • 發佈:2019-01-10
今天學了資料結構中的堆,堆分為大根堆和小根堆。大根堆是什麼呢?大根堆是指一顆即
是完全二叉樹又是大根樹的樹。那什麼是大根樹,和完全二叉樹呢?去百度google一下就知道了。
小根堆是一個與大根堆類似的概念,聯想一下吧。
大根堆和小根堆有何用呢?用處當然是有的,有人說可以用來實現大值優先佇列和小值優
先佇列。所以下面就大根堆來實現一個大值優先佇列heap。這個佇列提供兩個操作函式,一個是
push,一個是pop。push是把一個節點入列,pop是把節點出列,也就是刪除一個節點。
下面是程式碼實現
#include <stdlib.h> #include <stdio.h> #define MAX_ELEMENTS 200 #define HEAP_FULL(n) (n == MAX_ELEMENTS - 1) #define HEAP_EMPTY(n) (!n) typedef struct { int key; char c; /* add other fields */ } element; element heap[MAX_ELEMENTS]; void push(element item, int *n) { int i = 0; if(HEAP_FULL(*n)) { fprintf(stderr, "The heap is full.\n"); exit(0); } i = ++(*n); while(i != 1 && item.key > heap[i / 2].key) { heap[i] = heap[i / 2]; i /= 2; } heap[i] = item; } // delete element with the highest key from the heap element pop(int *n) { int parent = 0, child = 0; element item, temp; if(HEAP_EMPTY(*n)) { fprintf(stderr, "the heap is empty.\n"); exit(0); } // save value of the element with the highest key item = heap[1]; // use last element in heap to adjust heap parent temp = heap[(*n)--]; parent = 1; child = 2; while(child <= *n) { // find the larger child of the current parent if(child < *n && heap[child].key < heap[child + 1].key) child++; if(temp.key >= heap[child].key) break; // move to the next lower level heap[parent] = heap[child]; parent = child; child *= 2; } heap[parent] = temp; return item; } int main() { int n = 0; // node counts int num[] = {2, 5, 18, 7, 9, 4, 3}; element item; // push all node into queue for(int i = 0; i < sizeof(num) / sizeof(int); i++) { item.key = num[i]; item.c = 'a'; push(item, &n); } // pop all node out of queue while(n > 0) { item = pop(&n); printf("item.key = %d, ch = %c\n", item.key, item.c); } getchar(); return 0; }
大家可以把程式碼拷貝除錯看看,會發現在記憶體heap中不是按key值從大到小排列的,但pop列印的數值是從大到小,很神奇吧。