堆,是一种完全二叉树。而且在这颗树中,父节点必然大于(对于小顶堆为小于)子节点。
关于树的概念不了解可以看这里:http://www.cnblogs.com/HongYi-Liang/p/7231440.html
由于堆是一种完全二叉树,很适合保存为数组的形式。如下图示意的堆,红色数字为数组索引,黑色数字为数组的值,那么这个堆保存为数组的形式:heap={9,8,5,6,7,1,4,0,3,2};
值得注意的是,在堆中,若设父亲的索引为i,左儿子的索引刚好等于2i,而右儿子的索引等于2i+1。这个公式会大量地出现在下边的程序中。
关键概念:
大顶堆:树根元素为最大值往叶子递减,(父节点总是大于子节点)
小顶堆:树根元素为最小值往叶子递增,(父节点总是小于子节点)
下为一个大顶堆的示意图,父节点总是大于子节点
在下面的程序中,C将以大顶堆的形式编写,C++以小顶堆的形式编写。
程序源码:
本例子为大顶堆,包含4个文件(如下图)
MaxHeap.c
#include "MaxHeap.h" bool MaxHeapConstructByBuffer(MaxHeap *heap,MAXHEAP_ELEM buff[],int length); bool MaxHeapDesturct(MaxHeap *heap); bool MaxHeap_getSize(MaxHeap *heap); bool MaxHeap_isFull(MaxHeap *heap); bool MaxHeap_isEmpty(MaxHeap *heap); void MaxHeap_swap(MAXHEAP_ELEM *a,MAXHEAP_ELEM *b); void MaxHeap_floating(MaxHeap *heap,int index); void MaxHeap_sink(MaxHeap *heap, int index); bool MaxHeap_push(MaxHeap *heap,MAXHEAP_ELEM data); bool MaxHeap_push(MaxHeap *heap,MAXHEAP_ELEM data); bool MaxHeap_pop(MaxHeap *heap,int index); void MaxHeap_printfAll(MaxHeap *heap); bool MaxHeapConstructByBuffer(MaxHeap *heap,MAXHEAP_ELEM buff[],int length) { int i; if(NULL != heap->iDatas) { return false; } heap->iHeapCapacity=length; heap->iHeapSize=0; heap->iDatas = (MAXHEAP_ELEM*)malloc(sizeof(MAXHEAP_ELEM)*length); for(i=0;i<length;i++) { MaxHeap_push(heap,buff[i]); } return true; } bool MaxHeapDesturct(MaxHeap *heap) { if(NULL == heap->iDatas) { return false; } free(heap->iDatas); return true; } bool MaxHeap_getSize(MaxHeap *heap) { return heap->iHeapSize; } bool MaxHeap_isFull(MaxHeap *heap) { if(heap->iHeapCapacity == heap->iHeapSize) { return true; } return false; } bool MaxHeap_isEmpty(MaxHeap *heap) { if(0 == heap->iHeapSize) { return true; } return false; } void MaxHeap_swap(MAXHEAP_ELEM *a,MAXHEAP_ELEM *b) { MAXHEAP_ELEM temp; temp=*a; *a=*b; *b=temp; } void MaxHeap_floating(MaxHeap *heap,int index) { int i; for(i=index;i>0;i=(int)(i*0.5)) { if(heap->iDatas[i-1] > heap->iDatas[(int)(i*0.5-1)] ) { MaxHeap_swap(&heap->iDatas[i-1],&heap->iDatas[(int)(i*0.5-1)]); } else { break; } } } void MaxHeap_sink(MaxHeap *heap, int index) { int i=index; while(i*2<=heap->iHeapSize) { if(heap->iDatas[i-1] < heap->iDatas[i*2-1])//it compare to left child { MaxHeap_swap(&heap->iDatas[i-1],&heap->iDatas[i*2-1]); if(i*2+1<=heap->iHeapSize && heap->iDatas[i-1] < heap->iDatas[i*2])//it compare to right child { MaxHeap_swap(&heap->iDatas[i-1],&heap->iDatas[i*2]); } /*index*/ i=i*2; } else if(i*2+1<=heap->iHeapSize && heap->iDatas[i-1] < heap->iDatas[i*2])//it compare to right child { MaxHeap_swap(&heap->iDatas[i-1],&heap->iDatas[i*2]); i=i*2+1; } else { break; } } } bool MaxHeap_push(MaxHeap *heap,MAXHEAP_ELEM data) { if( MaxHeap_isFull(heap)) return false; heap->iDatas[heap->iHeapSize]=data; heap->iHeapSize++; MaxHeap_floating(heap,heap->iHeapSize); return true; } bool MaxHeap_pop(MaxHeap *heap,int index) { if(MaxHeap_isEmpty(heap)) return false; heap->iDatas[index]=heap->iDatas[heap->iHeapSize-1]; heap->iHeapSize--; MaxHeap_sink(heap,index+1); return true; } void MaxHeap_printfAll(MaxHeap *heap) { int i; printf("heap:"); for( i=0;i<heap->iHeapSize;i++) { printf("%d ",heap->iDatas[i]); } printf("\r\n"); }