堆,是一种完全二叉树。而且在这颗树中,父节点必然大于(对于小顶堆为小于)子节点。

关于树的概念不了解可以看这里: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++的实现

 

在下面的程序中,C将以大顶堆的形式编写,C++以小顶堆的形式编写。


 

程序源码:

本例子为大顶堆,包含4个文件(如下图)

数据结构-堆 C与C++的实现

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");
}
View Code

相关文章: