深度解析堆排序

此篇为原创,如需转载,请注明出处:http://blog.csdn.NET/qq_36759732

堆排序,其实就是用数组存储,利用完全二叉树的性质,对其进行二叉树的操作,通过构建大顶堆(小顶堆),找到最大值(最小值),与最后一个节点交换,然后总个数减一,然后重复此操作,最后得到有序序列。(如果不理解大顶堆与小顶堆的话,建议先看看)

基本思路是:1,构建出始堆;2,将堆顶元素与最后一个节点交换;3,递归此操作。

感觉思路很简单是吧 ,那就直接上代码

  1 #include<iostream>
  2
  3 using std::cin;
  4 using std::cout;
  5 using std::endl;
  6
  7 #define MAX 100
  8
  9 #define swap(a, b){ \
 10   __typeof(a) __t = a; \
 11   a = b;b = __t; \
 12 }
 13
 14 void updata_heap(int arr[], int father, int n){
 15   int lchild = 2 * father + 1; //左孩子
 16   int rchild = 2 * father + 2; //右孩子
 17   int max_index = father; //临时变量
 18   if(father < n / 2){
 19       if(lchild < n && arr[lchild] > arr[max_index]){
 20           max_index = lchild;
 21       }
 22       if(rchild < n && arr[rchild] > arr[max_index]){
 23           max_index = rchild;
 24       }
 25       if(max_index != father){ //交换后破环了子树的堆结构
 26             swap(arr[max_index], arr[father]);
 27             updata_heap(arr, max_index, n);
 28       }
 29   }
 30   return ; 
 31 }

 32
 33 void heap_build(int arr[], int n){ //建立大顶堆
 34   for(int father = (n - 1) / 2; father >= 0; --father){
 35     updata_heap(arr, father, n);
 36   }
 37 }
 38
 39 void heap_sort(int arr[], int n){
 40   
 41   heap_build(arr, n);
 42   
 43   for(int i = n - 1; i > 0; --i){
 44     swap(arr[0], arr[i]);//根元素(最大值)的与最后一个节点交换
 45     updata_heap(arr, 0, i); //重新建立大顶堆
 46   }
 47
 48 }
 49
 50 void output(int arr[], int n){ //输出
 51   cout << "有序数果arr:" << " ";
 52   for(int i = 0; i < n; ++i){
 53       cout << arr[i] << " ";
 54   }
 55   cout << endl;
 56   return ;
 57 }
 58
 59 int main(){
 60   int n;
 61   int arr[MAX];
 62   cout << "待排个数:";
 63   cin >> n;
 64   cout << "输入待排序数列arr:";
 65   for(int i = 0; i < n; ++i){
 66     cin >> arr[i];
 67   }
 68   heap_sort(arr, n);
 69   output(arr, n);
 70   return 0;
 71 }


!!!需要注意的是,数组从0开始和从1开始左右孩子的标号会有变化,这个是从0下标开始的。

结果如下:


以上是本人对堆排序操作的理解,欢迎大家指点与修正,后面还有其他排序的操作,大家敬请期待。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值