排序6之堆排序

 在进行堆排序之前必须知道堆的性质。

堆分为大根堆和小根堆,我们只说下大根堆,小根堆其实和大根堆没多大区别:

ki>=k(2i)且ki>=k(2i+1)(1≤i≤ n),当然,这是大根堆,小根堆则换成<=号。//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子

#include <stdlib.h>//堆排序
#include <stdio.h>
#include <string.h>
#define swap(x,y) {int t=x;x=y;y=t;}
#define N 10
int len;
void kph(int *a,int n)//堆的性质维护
{  //该函数实现前提是:以节点n的左右孩子为根的二叉树是堆
       int k=n,l,r;
    l=k*2; r=l+1;
      if(r<=len)
   {
    if(a[l]<a[r])
     swap(l,r);
    if(a[l]>a[k])
    {
      swap(a[k],a[l]);
               kph(a,l);
    }
        return ;
   }
   else
   {
       if(l<=len)
         if(a[l]>a[k])
           swap(a[l],a[k]);
        return ;
   }
}
void ch(int *a,int n)//堆的建立
{
  int i,k;
   scanf("%d",&a[1]);
  for(i=2;i<=n;i++)
  {
     scanf("%d",&a[i]);
       k=i;
 while(k>1&&a[k]>a[k/2])
        {
            swap(a[k],a[k/2]);
            k=k/2;
        }
  }
}
void hs(int *a,int n)//堆排序
{
 len=n;
  while(len>1)
  {
   swap(a[1],a[len]);
      len--;
   kph(a,1);
  }
}
int main()
{
 int i;
 int a[N+1];
 memset(a,0,sizeof(a));
 ch(a,N);//堆的建立
 hs(a,N);
   for(i=1;i<=N;i++)
    printf("%d ",a[i]);
   printf("\n");
  return 0;
}

                                                      --------江财小子

原文地址:https://www.cnblogs.com/372465774y/p/2421633.html