题目:
利用最小堆对数字排序,第一行为数字个数,第二行为具体的数字。
14
99 5 36 7 22 17 46 12 2 19 25 28 1 92
代码:
#include <stdio.h>
int h[101];
int n;
//交换函数
void swap(int x,int y)
{
int t;
t=h[x];
h[x]=h[y];
h[y]=t;
}
//向下调整函数
void siftdown(int i)
{
int t,flag=0;
//当i有儿子时,并且flag=0时,执行循环
while(i2<=n && flag==0)
{
//比较i节点的值和它左儿子的值
if (h[i]>h[i2])
{
t=i*2;
}
else t=i;
//判断i是否有右儿子
if (i*2+1<=n)
{
//比较i节点的值和它右儿子的值
if (h[t]>h[i*2+1])
{
t=i*2+1;
}
}
//这里我表述不来,需要自己代入具体的数值去体会
if (t!=i)
{
swap(t,i);
i=t;
}
else flag=1;
}
}
//建立最小堆的函数
void creat()
{
int i;
for (i=n/2;i>=1;i–)
{
siftdown(i);
}
}
//删除最大的节点
int deletemax()
{
int t;
//t用来暂存根节点的值(即编号为1的值)
t=h[1];
//用最后一个节点的值替换根的值
h[1]=h[n];
//去掉最后一个叶节点
n–;
//最新生成的树进行向下调整
siftdown(1);
return t;
}
int main()
{
int i,num;
//读入节点数
scanf("%d",&num);
//用一个完全二叉树存放读入的num个数
for (i=1;i<=num;i++)
{
scanf("%d",&h[i]);
}
n=num;
//将上面形成的二叉树变成最小堆的形式(最小堆:所有的子节点的值都大于父节点的值)
creat();
//由小到大,逐个输出
for (i=1;i<=num;i++)
{
printf("%d ",deletemax());
}
return 0;
}
测试结果:
1 2 5 7 12 17 19 22 25 28 36 46 92 99