代码实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int num;
void buildheap(int *a,int i,int n) //构造堆
{
int c,temp;
for (temp=a[i];2*i<=n;i=c) //temp记录父亲节点的值,c为其左孩子节点,//2*i<=N,i=c当结点还有孩子节点时,将i指向其左孩子节点,继续循环
{
c=2*i; //i的左孩子节点编号为2*i
if(c<n&& a[c+1]>a[c]) //找到i最大的孩子节点(左孩子和右孩子比较)
++c; //将最大的孩子编号给c
if(temp<a[c]) //父亲节点值等于孩子节点和本身中最大的
a[i]=a[c];
else
break; //父亲节点最大,直接跳出循环
}
a[i]=temp; //将原本的“根节点”a[i]的值赋值给最后被交换的节点
}
void heapsort(int *a) //排序
{
int i,temp;
for(i=num/2;i>=1;i--) //从((num/2)为最后一个父亲节点)最后一个父亲节点开始构造堆,一直向上,构造到根节点。
{
buildheap(a,i,num);
}
for(i=num;i>1;i--) //删除根节点后,重新构造堆//i>1而不i>0的原因:当i=1时二叉树中只有一个元素,而不需要对其再进行一次构造堆了,他本身就是最大的了。
{
temp=a[1];
a[1]=a[i];
a[i]=temp;
buildheap(a,1,i-1);
}
}
int main(int argc, char *argv[])
{
printf("堆排序\n");
printf("请输入要排序的元素的个数:");
scanf("%d",&num);
int i,a[num+1];
printf("请输入元素:");
for(i=1;i<num+1;i++)//根节点i=1,与数组a大小为num+1的意义:根节点编号为1时,值为a[1],其左孩子节点编号为2*i=2,值为a[2]。同理父亲节点编号为i,值为a[i],其左孩子节点编号为2*i,值为a[2*i]。这样可以方便得出,父亲节点和孩子节点的关系。//且易找出该二叉树中最后一个父亲节点为num/2。//根节点i=0也可以实现,只是运算,理解方面要复杂一些。
scanf("%d",&a[i]);
heapsort(a);
printf("排序后序列:\n");
for(i=1;i<num+1;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
结果演示