4.1b 堆的构建_哔哩哔哩_bilibili
// 大根堆的实现
#include<stdio.h>
#include<stdlib.h>
#define MAXN 1000
// 大根堆定义
typedef struct{
int elem[MAXN]; //元素数组
int len; //堆的大小
}HeapNode,*Heap;
// 向下调整:p位置元素下沉
void SiftDown(Heap H, int p, int n){
int e=H->elem[p]; //保存p元素
for(int i=2*p; i <= n; i *= 2){
if(i<n && H->elem[i] < H->elem[i+1]) i++;
if(e >= H->elem[i]) break;
H->elem[p] = H->elem[i];
p = i; //p位置下沉
}
H->elem[p] = e; //p元素达到合适位置
}
// 建堆:用数组a建大根堆
void CreateHeap(Heap H, int a[], int n){
H->len=n;
for(int i=1; i <= n; i++){
H->elem[i]=a[i-1];
}
// 从最后一个分支结点向前调整
for(int i=n/2; i > 0; i--){
SiftDown(H, i, n);
}
}
// 堆插入:堆尾插入元素,向上调整
void HeapInsert(Heap H, int e){
int i = ++H->len;
for( ; i>1; i /= 2){
if(H->elem[i/2] >= e) break;
H->elem[i] = H->elem[i/2];
}
H->elem[i] = e; //插入元素到达合适位置
}
// 堆删除:用堆尾替换堆顶,向下调整,返回堆顶元素
int HeapDelete(Heap H){
if(H->len <= 0) return -1;
int e = H->elem[1];
H->elem[1]=H->elem[H->len];
SiftDown(H, 1, --H->len);
return e;
}
// 堆排序:《排序》章会讲
void HeapSort(Heap H){
int temp;
for(int i=H->len; i > 1; i--){
temp=H->elem[1];
H->elem[1]=H->elem[i];
H->elem[i]=temp;
SiftDown(H,1,i-1);
}
}
// 打印堆数组
void PrintHeap(Heap H){
for(int i=1; i <= H->len; i++){
printf("%d ", H->elem[i]);
}
printf("\n");
}
int main(){
int a[]={1,5,2,5,6,9,7};
int n=sizeof(a)/sizeof(a[0]);
Heap H=(HeapNode*)malloc(sizeof(HeapNode));
CreateHeap(H, a, n);
printf("建堆结果:");
PrintHeap(H);
HeapInsert(H, 8);
printf("插入8后:");
PrintHeap(H);
int e=HeapDelete(H);
printf("删除堆顶元素:%d,剩余堆:",e);
PrintHeap(H);
HeapSort(H);
printf("堆排序后:");
PrintHeap(H);
free(H);
return 0;
}