码迷,mamicode.com
首页 > 其他好文 > 详细

heap_sort

时间:2019-03-29 23:35:59      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:turn   get   clu   nbsp   完整   lap   mic   for   logs   

技术图片(from wikipedia)

 

构建步骤:

  1. 建成一个大顶堆
  2. 第一个元素依次和最后一个元素交换,由于交换后新的堆顶元素可能违反大根堆的性质,因此需要对当前无序区(1,2,...,n-1)调整为新堆
  3. 不断重复此过程直到有序区的元素个数为n-1
  4. 排序完成

下面举例说明:

给定一个列表array=[16,7,3,20,17,8],对其进行堆排序。

首先根据该数组元素构建一个完全二叉树,得到

技术图片

然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:
第一步: 初始化大顶堆(从最后一个有子节点开始往上调整最大堆)

技术图片技术图片技术图片

20和16交换后导致16不满足堆的性质,因此需重新调整

技术图片这样就得到了初始堆。

第二步: 堆顶元素R[1]与最后一个元素R[n]交换,交换后堆长度减一

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

技术图片

第三步: 重新调整堆。此时3位于堆顶不满堆的性质,则需调整继续调整(从顶点开始往下调整)

技术图片技术图片

重复上面的步骤:

技术图片技术图片技术图片

技术图片技术图片

技术图片技术图片技术图片

不管是初始大顶堆的从下往上调整,还是堆顶堆尾元素交换,每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换,交换之后都可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整。(出自http://www.cnblogs.com/0zcl by前程明亮)

现在

开始

代码:

技术图片
int main(){
    
    cin>>n;
    for( int i=1; i<=n; i++){
        cin>>a[i];
    }
    
    heap_sort();
    
    for( int i=1; i<=n; i++){
        printf("%d ",a[i]);
    } 
    
    return 0;
}
main函数

(主函数不多说

技术图片
void heap_sort(){
    for( int i=n; i>=1; i--){
        update(i,n);
    }
    for( int i=n-1; i>=1; i--){
        swap(a[i+1],a[1]);
        update(1,i);
    }
} 
heap_sort

首先就是建立大根堆:

 for( int i=n; i>=1; i--)update(i,n); 

关于这个update函数是这样的:

  对输入的两个数组的地址 i 和 n

      • 如果 i 的左儿子比 n 还大,那么退出
      • 如果 i 的右儿子比左儿子大,那么把地址指向右儿子,否则地址是指向i 的左儿子的
      • 如果 t 指向的这个数组的值大于 n 指向的值,那么交换这两个值
      • 继续递归地update t 和 n

然后就是heap_sort的内涵:

技术图片
for( int i=n-1; i>=1; i--){
    swap(a[i+1],a[1]);
    update(1,i);
}
View Code

大致就是这样。

完整代码如下:

技术图片
#include <cstdio>
#include <iostream>
using namespace std;

int n;
int a[50005];

#define lson(x) (x*2)

void update(int x, int m){
    int t=lson(x);
    if(t>m)return ;
    if(t<m && a[t+1]>a[t])t++;
    if(a[t]>a[x])swap(a[x],a[t]);
    update(t,m);
}

void heap_sort(){
    for( int i=n; i>=1; i--){
        update(i,n);
    }
    for( int i=n-1; i>=1; i--){
        swap(a[i+1],a[1]);
        update(1,i);
    }
} 

int main(){
    
    cin>>n;
    for( int i=1; i<=n; i++){
        cin>>a[i];
    }
    
    heap_sort();
    
    for( int i=1; i<=n; i++){
        printf("%d ",a[i]);
    } 
    
    return 0;
}
View Code

 

 

heap_sort

标签:turn   get   clu   nbsp   完整   lap   mic   for   logs   

原文地址:https://www.cnblogs.com/gogoflower/p/10624791.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!