堆(heap)通常是一个可以被看做一棵树的数组对象。堆是非线性数据结构,相当于一维数组,有两个直接后继。堆总是满足下列性质:
-
堆中某个结点的值总是不大于或不小于其父结点的值;
-
堆总是一棵完全二叉树。
下面是堆的底层算法原理实现。
1.堆数据结构定义
#define DEFAULT_CAPCITY 128 //预定义一个最大容量
typedef struct _Heap{
int *arr; //存储堆元素的数组
int size;//当前已存储元素个数
int capacity; // 当前存储的容量
}Heap;
2.初始化堆
bool initHeap(Heap &heap,int*orginal,int size) //堆实例,给定数组,数组大小
{
int capacity=DEFAULT_CAPCITY>size?DEFAULT_CAPCITY:size;
heap.arr=new int[capacity];
if(!heap.arr) return false;
heap.capacity=capacity;
heap.size=0;
if(size>0) //如果数组里面有元素才建堆
{
memcpy(heap.arr,orginal,size*sizeof(int)); //最后一个参数为元素占空间大小
heap.size=size;
buildHeap(heap); //调用下面建堆方法
}
return true;
}
3.建堆
void buildHeap(Heap &heap)
{
int i;
for(i=heap.size/2-1;i>=0;i--)
{
adjustDown(heap,i); //调整堆的函数
}
}
4.向下调整堆
void adjustDown(Heap &heap,int index)
{
int cur=heap.arr[index];
int parent,child;
for(parent=index;(parent*2+1)<heap.size;parent=child)
{
child=parent*2+1;
if(((child+1)<heap.size)&&(heap.arr[child]<heap.arr[child+1])) //取两个子节点中的最大结点
{
child++;
}
if(cur>=heap.arr[child]) //判断节点是否大于父节点
{
break;
}
else{
heap.arr[parent]=heap.arr[child];
heap.arr[child]=cur;
}
}
}
5.向堆中插入元素
bool insert(Heap &heap,int value)
{
if(heap.size==heap.capacity) return false;
int index=heap.size;
heap.arr[heap.size++]=value;
adjustup(heap,index); //向上调整方法
return true;
}
6.向上调整堆
void adjustup(Heap &heap,int index)
{
if(index<0||index>=heap.size) return;
while(index>0)
{
int tmp=heap.arr[index];
int parent=(index-1)/2;
if(parent>=0)
{
if(temp>heap.arr[parent])
{
heap.arr[index]=heap.arr[parent];
heap.arr[parent]=temp;
index=parent;
}else
{
break;
}
}else{
break;
}
}
}