堆的简介
一般说堆,说的是二叉堆。堆数据结构是一种数组对象,它可以被看作为一棵完全二叉树。树中的每个节点与数组中存放该节点值的那个元素对应。堆有两个属性:堆能容纳的元素个数,堆中存放的元素个数。二叉堆有两种:大根堆和小跟堆,它们应该满足的性质:A[parent[i]]>=A[i]或A[parent[i]]<=A[i]。以下就是一个大根堆。
堆的操作
保持堆的性质
Heap * init_heap(){
Heap *p = (Heap *)malloc(sizeof(Heap));
p->array_addr = NULL;
p->capacity = 0;
p->size = 0;
return p;
}
/**调整heap中的第i个节点子树为大根堆**/int heap_adjust(Heap * const heap,const int i){ if(heap == NULL || heap != NULL && heap->array_addr == NULL) return 0; int left = i * 2 +1 ; int right = i * 2 + 2; int largest = i; int swap = 0; if(left < heap -> size && *(heap->array_addr + left) > *(heap->array_addr + largest)) largest = left; if(right < heap -> size && *(heap->array_addr + right) > *(heap->array_addr + largest)) largest = right; if(largest != i){ swap = *(heap->array_addr + i); *(heap->array_addr + i) = *(heap->array_addr + largest); *(heap->array_addr + largest) = swap; return heap_adjust(heap,largest); } return 1;}
/**构建大根堆 从下向上构建大根堆**/int build_heap(Heap * const heap){ if(heap == NULL || heap != NULL && (heap->array_addr == NULL || heap->capacity <= 0)){ return 0; } int i = (heap->capacity-1) / 2; for(;i >= 0;i--){ heap_adjust(heap,i); } return 1;}
堆排序
/**将堆顶元素与尾部元素对换
调整堆
**/
int heap_sort(Heap * const heap){
if(heap == NULL) return 0;
if(build_heap(heap)){
int i = heap -> capacity -1;
int swap = 0;
for(;i > 0 ;i--){
swap = *(heap -> array_addr + i);
*(heap -> array_addr + i) = *(heap -> array_addr + 0);
*(heap -> array_addr + 0) = swap;
heap -> size = heap -> size -1;
heap_adjust(heap,0);
}
return 1;
}else return 0;
}
优先队列
优先级队列支持如下操作:
1)取出最大元素,但不移除。
2)抽取最大元素
3)在指定位置,用key取代A[i]的值,但key必须比A[i]要大
4)在队列中增加元素
/**返回优先队列最大元素*/
int heap_max(Heap * const heap){
if(heap == NULL || heap -> size <1){
return -1;
}
return *(heap -> array_addr + 0);
}
/**A[0]与末位元素对调
从上至下调整队列
**/
int extract_max(Heap * const heap){
if(heap == NULL || heap -> size < 1 || heap -> array_addr == NULL) return -1;
int max = *(heap -> array_addr + 0);
*(heap -> array_addr + 0) = *(heap -> array_addr + heap -> size -1);
heap -> size -= 1;
heap_adjust(heap,0);
return max;
}
int increase_key(Heap * const heap,int i,int key){ if(heap == NULL || heap -> size < 1 || heap -> array_addr == NULL) return -1; if(key < *(heap -> array_addr + i)) return -1; *(heap -> array_addr + i) = key; int index = i; int swap = 0; while(index > 0 && *(heap -> array_addr + index) > *(heap -> array_addr + index / 2)){ swap = *(heap -> array_addr + index); *(heap -> array_addr + index) = *(heap -> array_addr + index / 2); *(heap -> array_addr + index / 2) = swap; index /= 2; }}int heap_insert(Heap * const heap,int key){ if(heap == NULL || heap -> size < 1 || heap -> array_addr == NULL) return -1; heap -> size += 1; *(heap -> array_addr + index) = INT_MIN; increase_key(heap,heap -> size - 1,key); return 1;}