C语言实现堆排序
算法步骤
把n个元素建立一个堆,从1到n进行编码,从而把n个结点转换成为一棵完成二叉树。然后从最后一个非叶结点(n/2)到根结点(1)根据需要向下调整,直到以当前结点为根结点的子树符合堆的特性。
每次将最小值提取到根结点后,输出根结点,然后将堆的最后一个元素添加到根结点,这样堆的大小就可以减一,不断重复此步骤,直到堆内元素为空,这样输出就得到了数据的从小到大排列。
代码实现
完整代码如下:
#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; //flag用来标记是否需要继续向下调整
//当i结点有儿子并且有需要继续调整的时候循环就执行
while(i*2<=n && flag == 0)
{
//首先判断它和左儿子的关系,并用t记录值较小的结点编号
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;
}
else
flag = 1;
}
}
//建立堆的函数
void creat()
{
int i;
//从最后一个非叶结点到第1个结点依次向上调整
for(i=n/2;i>=1;i--)
siftdown(i);
}
//输出最小数据
int deletemax()
{
int t;
t = h[1];
h[1] = h[n];
n--;
siftdown(1);
return t;
}
int main()
{
int i,num;
scanf("%d",&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;
}
理解清楚堆的特性,算法实现并不困难,一起加油ovo
O V E R