一、算法描述
大顶堆
- 父母节点为i,子女节点为2i和2i+1;子女节点为i,父母节点为i/2。
- 父母节点比子女节点大
- 树的结构是满的
堆排序
- 从最后一个父母节点开始,构造大顶堆,直到根节点
- 根节点与尾节点交换,相当于删除根节点,构造大顶堆,直到无法构造
二、堆排序代码
void build_sort(int a[],int i,int n)
{
int s,temp;
for(temp=a[i];2*i<=n;i=s)
{
s=2*i;
if(a[s]<a[s+1]&&s<n) s++;//子女结点较大的
if(temp<a[s]) a[i] = a[s];//较大的子女结点与父母结点比较
else break;
}
a[i] = temp;
}
void heap_sort(int a[],int N)
{
int i,temp;
for(i=N/2;i>=1;i--)//从最后一个父母结点开始
{
build_sort(a,i,N);
}
for(i=N;i>0;i--)//根结点与尾结点交换,构造大顶堆
{
temp = a[i];
a[i] = a[1];
a[1] = temp;
build_sort(a,1,i-1);
}
}
三、测试代码
#include<stdio.h>
void build_sort(int a[],int i,int n)
{
int s,temp;
for(temp=a[i];2*i<=n;i=s)
{
s=2*i;
if(a[s]<a[s+1]&&s<n) s++;
if(temp<a[s]) a[i] = a[s];
else break;
}
a[i] = temp;
}
void heap_sort(int a[],int N)
{
int i,temp;
for(i=N/2;i>=1;i--)
{
build_sort(a,i,N);
}
for(i=N;i>0;i--)
{
temp = a[i];
a[i] = a[1];
a[1] = temp;
build_sort(a,1,i-1);
}
}
int main()
{
int N,i;
printf("请输入需要排序的数的个数:\n");
scanf("%d",&N);
int a[N];
printf("请输入需要排序的数:\n");
for(i=0;i<N;i++)
scanf("%d",&a[i]);
heap_sort(a,N);
printf("堆排序的结果:\n");
for(i=0;i<N;i++)
printf("%d ",a[i]);
}