堆排序( 内部排序 续 )

昨天老师讲了最后一个内部排序方法:堆排序。刚开始听的时候,比较晕。回来自己想了一会儿,豁然开朗...呵呵。真是佩服那些做算法研究的人。牛X。

堆:假设为大根堆,则 a[i] >= max{ a[2i+1], a[2i+2] } , a[i] 为 parent, a[2i+1], a[2i+2] 为其左/右儿子。

堆排序: 选择排序的优化。逻辑抽象(顺序地为数组元素下标编号)出一颗完全二叉树(自上而下 && 从左到右, 除最后一层叶子外,其余都为满树)。然后循环取出根节点+调节堆。堆排序在最坏情况下的时间复杂度为 nlg(n),而且其空间利用率相对高,除了一个temp外,几乎没有花费另外的存储空间,这点远远好于归并排序。

堆排序在一维简单数组上的实现:
#include <iostream>
using namespace std;

// Pre: low 到 high 之间除了low 以外都符合堆。
// Post: low 到 high 都满足堆条件。
void heapify( int a[], int low, int high )
{
 bool fini=false;      // fini 代表 finished, bool flag。
 int temp = a[low];  int i = low;       // 把 a[low], 和 low 先备份一下。
 int j = 2*low +1;

// 找到第一个<= a[low] 的 位置。
 while( j<=high && !fini )
 {
  if( j<high && a[j]<a[j+1] )
   j++;
  if( a[j] <= a[low] )
   fini = true;
  else { a[i]=a[j]; i=j;  j = 2*j+1; }
 }
 a[i] = temp;  // not a[j] = temp;
}

void heap_sort( int a[], int n )  // l_n : stands for last_unsorted.
{
// for 循环建堆。 没有必要从 n-1 开始,因为叶子肯定是满足堆结构的,我们从第一个“可能”不满足对结构的位置(n/2 -1 开始)
 for( int i= n/2 -1; i>=0; --i )  
  heapify( a, i, n-1 );

 for( int l_n = n-1; l_n >=1 ; --l_n )
 {
  swap( a[0], a[l_n] );
  heapify( a, 0, l_n-1 );
 }
}

void main()
{
 int a[5]= { 2, 1, 7, 9, 7 };
 heap_sort( a, 5 );
 for( int i =0; i<5; ++i )
  cout<<a[i]<<"  "<<flush;
 cout<<endl;

 cin.get();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值