堆的概念及结构
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
- 堆从逻辑上讲是一棵完全二叉树,从物理存储上讲则是一个数组。
- 堆的基本功能:寻找最大值、最小值。
堆的性质
- 堆中某个节点的值总是不大于或不小于其父节点的值
- 堆总是一棵完全二叉树
堆的实现
1、向下调整算法
现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
void heapify(int a[],int szie,int index){
while(1){
int left=2*index+1;
int right=2*index+2;
if(left>=size)
return;
int min=left;
if(right<size&&a[right]<a[left]){
min=right;
}
if(a[index]<=a[min]){
return;
}
int t=a[min];
a[min]=a[index];
a[index]=t;
index=min;
}
}
2.建堆
void createHeap(int a[],int size){
for(int i=(size-2)/2;i>=0;i--){
heapify(a,size,i);
}
}
typedef struct Heap{
int array[100];
int size;
}Heap;
void HeapInit(Heap *heap, int a[], int size){
for (int i = 0; i < size; i++){
heap->array = a[i];
}
heap->size = size;
creatHeap(heap->array, heap->size);
}
3.向上调整算法
void adjustUp(int a[], int index){
if (index == 0){
return;
}
int parent = (index - 1) / 2;
if (a[parent] <= a[index]){
return;
}
int t = a[parent];
a[parent] = a[index];
a[index] = t;
index = parent;
}
void HeapPush(Heap *heap, int val){
heap->array[heap->size++] = val;
adjustUp(heap->array, heap->size - 1);
}
4.堆的删除
void HeapPop(Heap *heap){
assert(heap - >size > 0);
heap->array[0] = heap->array[heap->size - 1];
heap->size--;
heapify(int a[], int size, int index);
}