堆,是一颗完全二叉树,且任一结点大于等于其左右孩子结点。
代码如下,详见注释:
输入:
10
85 55 82 57 68 92 99 98 66 56
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 110;
int heap[maxn] = {0};
int n;
void downAdjust(int low, int high){
int i = low, j = 2*i;
while(j<=high){ //结点i存在孩子
if(j+1<=high&&heap[j+1]>heap[j]){ //右孩子大于父亲结点i,且右孩子大于左孩子
j = j+1;
}
if(heap[j]>heap[i]){
swap(heap[j],heap[i]);
i = j; //保持i为预调节结点
j = i*2;
}else{
break;
}
}
}
void upAdjust(int low, int high){
int i = high, j = i/2;
while(j>=low){ //父亲在[low,high]内
if(heap[j]<heap[i]){
swap(heap[i], heap[j]);
i = j; //保持i为预调节结点
j = i/2;
}else{
break;
}
}
}
void createHeap(){ //倒着枚举,[1,n/2]一定为非叶子结点
for(int i=n/2;i>=1;i--){
downAdjust(i, n);
}
}
void deleteTop(){
swap(heap[1],heap[n--]);
downAdjust(1, n);
}
void sortHeap(){
int m = n;
while(m>1){
swap(heap[1], heap[m--]);
downAdjust(1, m);
}
}
int main(){
scanf("%d", &n);
for(int i=1;i<=n;i++){
scanf("%d", heap+i);
}
createHeap();
for(int i=1;i<=n;i++){ //构成堆,父亲结点一定大于等于孩子结点
printf("%d ", heap[i]);
}
printf("\n");
//删除堆顶元素
deleteTop();
//添加元素70
n++;
heap[n] = 70; //100
upAdjust(1, n);
for(int i=1;i<=n;i++){ //构成堆,父亲结点一定大于等于孩子结点
printf("%d ", heap[i]);
}
printf("\n");
//堆排序
sortHeap();
for(int i=1;i<=n;i++){ //递增排序
printf("%d ", heap[i]);
}
return 0;
}
运行截图: