今天学了数据结构中的堆,堆分为大根堆和小根堆。大根堆是什么呢?大根堆是指一颗即
是完全二叉树又是大根树的树。那什么是大根树,和完全二叉树呢?去百度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打印的数值是从大到小,很神奇吧。