堆排序

因为堆是完全二元树,因此将堆以数组形式存储非常方便。设堆大小为Ni是其中一个元素,则这种堆满足的关系为:对所有的i <= n/2 - 1a[i] <= a[2*i]a[i] <= a[2*i+1]。当然这是小根堆,大根堆将<=改为>=即可。于是堆的第一个元素为最小元素,要实现排序只要依次取第一个元素,并用最后一个元素替代之。这样之后的只有第一个元素不符合堆定义,需要将它下推到合适位置。完成该功能的函数如下

//将堆顶元素下推至合适位置。a为堆数组,n为堆大小,i为堆顶元素下标

void push(int a[], int n, int i)

{

       int t;

       while( i < n/2 ){

       t = 2*i + 2 < n  -1 ? 2*i + 2 : n - 1;//ti的右儿子,没右儿子则为n,此时也即左儿子

       if( a[2*i + 1] < a[t])

              t = 2*i + 1;//ti的较小的儿子

       if( a[i] > a[t]){

              //交换元素

              a[i] = a[i] ^ a[t];

              a[t] = a[t] ^ a[i];

              a[i] = a[i] ^ a[t];

 

              i = t;

       }

       else

              break;

}

}

现在问题是如何将初始数组整理成堆。实际上利用上述下推函数即可简单地整理,从堆的最后一个非叶结点开始依次向前遍历,每次将当前元素作为堆的顶元素调用上述函数,因为此时当前元素以后的元素都符合堆的定义。

至此堆排序可以实现如下:

//堆排序。 a为堆数组,n为堆大小

void HeapSort(int a[], int n)

{

       int i;

//初始堆整理

       for(i = n/2 - 1; i >= 0; i--)

              push(a,n,i);

       //开始排序,排序后数组元素按从大到小排列

       for(i = n - 1; i > 0; i--){

              //将堆顶元素(即最小元素)与最后元素交换

              a[0] = a[0] ^ a[i];

              a[i] = a[i] ^ a[0];

              a[0] = a[0] ^ a[i];

 

              push(a,i , 0);//重新整理堆,每循环一次此堆大小减1

       }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值