您的位置:首页 > 其它

堆排序

2015-07-16 19:41 225 查看
//堆排序的根据是什么,就是每个堆的顶部的元素一定是最小值,那么我先建一个堆,每次记录下堆顶元素,然后把重新排列(这里有点技巧),减少堆的元素个数。

//注意堆的n是会变化,所以要先记录下来。

//处于同一层的节点大小不能判断,所以每次提取了堆顶元素就必须重新维护一次。(代码在sort部分)

#include <stdio.h>
int a[101];
int n;
void down(int i)
{
    int temp,t;
    while(i*2<=n)
    {
        if (a[i]>a[i*2])
        t=i*2;
        else
        t=i;
    if ((i*2+1<=n)&&(a[t]>a[i*2+1]))
        t=i*2+1;
    if (t!=i)
    {

        temp=a[t];
        a[t]=a[i];
        a[i]=temp;
        i=t;
    }
    else break;
    }
    return;

}
int sort()
{
    int t;
    t=a[1];//每次先记录下堆顶的元素
    a[1]=a
;//修改堆顶的元素,再对堆进行整理
    n--;//注意是先将元素个数减少一个,再维护(因为此时第一个元素已经被拿出,换成了最后一个元素,即原本最后一个元素的位置不需要了)
    down(1);
    return t;
}
 int main()
 {

     int i,num;
     scanf("%d",&n);
     num=n;//注意了这里的n是会变化的,所以要先记录下n的值(好吧,我查了好久才找到错这~~)
   for (i=1;i<=n;i++)
    scanf("%d",&a[i]);
   for (i=n/2;i>=1;i--)
     down(i);
    for (i=1;i<=num;i++)
    printf("%d ",sort());
       printf("\n");
        return 0;
 }


//这种方式无法用原来数组来保存元素,即是在原来的堆上进行修改得到的数据,那么有没有一种结果本身就是用堆来保存的从小到大的方法呢

//第二种方法就是先建立最大堆,则堆顶元素一定为当前堆内的最大元素,把它放在堆尾,并n--,使其不会改变,接着如法炮制,找出第二大,第三大元素。。,直到只剩一个元素

//该方法最后得到的是堆内按照下标顺序,已经是从大到小有序的,而不是第一种方法,边输出,边找下一个元素,因而在某些特定要求下会更加方便~~

#include <stdio.h>
 int a[101];
 int n;
 void down(int i)
 {
     int temp,t;
     while (i*2<=n)
     {

         if (a[i]<a[i*2])
            t=2*i;
         else t=i;
         if ((i*2+1<=n)&&(a[t]<a[i*2+1]))
            t=2*i+1;
         if (t!=i)
         {

             temp=a[t];
             a[t]=a[i];
             a[i]=temp;
             i=t;
         }
         else break;
     }

 }
 void sort()
 {
      int temp;
     while (n>1)
    {
     temp=a
;
     a
=a[1];//此时堆顶元素就是最大值
     a[1]=temp;//因此将堆顶元素与最后一个元素交换
     n--;//最后一个元素已经确定(位置是正确的),只需再对前n-1个数进行同样的考察
     down(1);
    }

 }
 int main()
 {
  int i,num;
  scanf("%d",&n);
  num=n;//同样要先记录下n
  for (i=1;i<=n;i++)
    scanf("%d",&a[i]);
    for (i=n/2;i>=1;i--)
        down(i);//建立最大堆
    sort();
    for (i=1;i<=num;i++)
        printf("%d ",a[i]);
    return 0;

 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: