今天學了資料結構中的堆,堆分為大根堆和小根堆。大根堆是什麼呢?大根堆是指一顆即
是完全二叉樹又是大根樹的樹。那什麼是大根樹,和完全二叉樹呢?去百度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 heapelement 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 keyitem = heap[1];// use last element in heap to adjust heap parenttemp = heap[(*n)--];parent = 1;child = 2;while(child <= *n){// find the larger child of the current parentif(child < *n && heap[child].key < heap[child + 1].key)child++;if(temp.key >= heap[child].key)break;// move to the next lower levelheap[parent] = heap[child];parent = child;child *= 2;}heap[parent] = temp;return item;}int main(){int n = 0; // node countsint num[] = {2, 5, 18, 7, 9, 4, 3};element item;// push all node into queuefor(int i = 0; i < sizeof(num) / sizeof(int); i++){item.key = num[i];item.c = 'a';push(item, &n);}// pop all node out of queuewhile(n > 0){item = pop(&n);printf("item.key = %d, ch = %c\n", item.key, item.c);}getchar();return 0;}大家可以把代碼拷貝調試看看,會發現在記憶體heap中不是按key值從大到小排列的,但pop列印的數值是從大到小,很神奇吧。