本人对最小堆的理解,相关注释在代码中
#include<iostream>
using namespace std;
const int maxn =10000000;
int h[maxn];//用一个一维数组模拟最小堆,父节点的的值小于子节点的值
int n;//用来记录堆的元素的个数
void swap(int x,int y){
int temp = 0;
temp = h[x];
h[x] = h[y];
h[y] = temp;
return;
}
//向下调整函数
void siftdowm(int i){//i作为插入元素向下调的数;
int t,flag=0;//t 作为最初的数,以及插入元素的向下调整时的原位置,即子树的根节点
while(i*2<=n && flag == 0){//i*2<n即还存在左节点 ,flag即新增元素还未到达正确位置,未构成最小堆
if( h[i] > h[i*2]) t= i*2;
else t = i;
if( i*2+1<=n ){
if( h[t] > h[i*2+1] ) t = i*2+1;
}
if( t!= i){
swap(t,i);//i,t实际上是节点的标号,交换的实际上是节点的值,并未交换 i ,t 的值
i = t;
}
else flag = 1;
}
}
//以上代码块控制堆是最大堆还是最小堆,堆是树的一种表达方式
//建立堆的函数
void creat(){
int i;
for(i=n/2;i>=1;i--) siftdowm(i);//从最后的一个非叶节点到第一个节点;
//为什么不从最后一个叶节点开始,因为最后一层下面已经没有元素了,不需要再向下调整,节省时间复杂度
}
// 删除最大的元素
int deletmax(){
int t;
t = h[1];
h[1] = h[n];
n--;
siftdowm(1);
return t;
}
int main(){
int i,num;
cin>>num;
for(i=1;i<=num;i++) cin>>h[i];
n= num;
creat();
for(i=1;i<=num;i++) cout<<deletmax()<<"\t";//其实这是个堆排序的模板
return 0;
}