堆排序两种写法

#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