#include <stdio.h> //
#include <stdlib.h>
#define maxn 1000
int a[maxn];
void buildheap(int low,int high)
{
while(1)//除非满足大顶堆性质 否则不断的检查
{
int i=2*low;//左
int j=i+1;//有孩子
int cursor=i;
if(i>high)
break;
if(j<=high&&a[j]>a[i])//如果右孩子存在并且大于左孩子 游标指向右孩子 否则指向左孩子
{
cursor=j;
}
if(a[cursor]>a[low])
{
int temp=a[low];
a[low]=a[cursor];
a[cursor]=temp;
low=cursor;
}
else
break;
}
/* int temp =a[low]; //整个过程中low永远指向的是之前的堆顶的元素需要插入的位置
for(int i=2*low;i<=high;i*=2)//这个步长表示下次继续从low这个位置继续检查是否满足大顶堆性质
{
if(i+1<=high&&a[i+1]>a[i])//如果有右孩子比左孩子大
{
i++;
}
if(a[low]<a[i]) //如果该节点比孩子结点小则需要交换
{
a[low]=a[i];
low=i;
}
else
break;
}
a[low]=temp;*/
}
void heapsort(int n)
{
for(int i=n;i>=2;--i) //每次无序区的最后一个元素不断的往前移动
{
int temp=a[1];//把堆顶最大的元素跟最后一个元素交换
a[1]=a[i];
a[i]=temp;
buildheap(1,i-1);
for(int j=1;j<=n;++j)
printf("%d ",a[j]);
printf("\n");
}
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=1;i<=n;++i)
{
scanf("%d",&a[i]);
}
for(i=n/2;i>=1;--i) //建立大根堆 从第一个非叶子结点开始调整大根堆
{
buildheap(i,n);//i是当前需要调整的父节点 n是控制结点下标的范围
}
heapsort(n);
return 0;
}
堆排序两种写法
猜你喜欢
转载自blog.csdn.net/qq_40795475/article/details/89592082
今日推荐
周排行