(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=; i<=n; i++){
cin>>a[i];
} heap_sort(); for( int i=; i<=n; i++){
printf("%d ",a[i]);
} return ;
}

main函数

(主函数不多说

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

heap_sort

首先就是建立大根堆:

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

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

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

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

然后就是heap_sort的内涵:

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

大致就是这样。

完整代码如下:

#include <cstdio>
#include <iostream>
using namespace std; int n;
int a[]; #define lson(x) (x*2) void update(int x, int m){
int t=lson(x);
if(t>m)return ;
if(t<m && a[t+]>a[t])t++;
if(a[t]>a[x])swap(a[x],a[t]);
update(t,m);
} void heap_sort(){
for( int i=n; i>=; i--){
update(i,n);
}
for( int i=n-; i>=; i--){
swap(a[i+],a[]);
update(,i);
}
} int main(){ cin>>n;
for( int i=; i<=n; i++){
cin>>a[i];
} heap_sort(); for( int i=; i<=n; i++){
printf("%d ",a[i]);
} return ;
}

heap_sort的更多相关文章

  1. 堆排序Heap_Sort

    堆排序就是借助二叉堆进行排序,不了解二叉堆的可以先看这里.本文以升序排序为例,首先将待排序数组放置在最小堆中,此时堆顶一定是数组中最小的元素,然后删除堆顶元素,此时调整后的最小堆顶会是第二小的元素,从 ...

  2. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  3. 七种机器内部排序的原理与C语言实现,并计算它们的比较次数与移动次数。

    内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 排序是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列.排序分为 ...

  4. 基于python的七种经典排序算法

    参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...

  5. 基本排序算法的Python实现

    本篇主要实现九(八)大排序算法,分别是冒泡排序,插入排序,选择排序,希尔排序,归并排序,快速排序,堆排序,计数排序.希望大家回顾知识的时候也能从我的这篇文章得到帮助. 为了防止误导读者,本文所有概念性 ...

  6. leetcode bugfree note

    463. Island Perimeterhttps://leetcode.com/problems/island-perimeter/就是逐一遍历所有的cell,用分离的cell总的的边数减去重叠的 ...

  7. Python学习路程day17

    常用算法与设计模式 选择排序 时间复杂度 二.计算方法 1.一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费 ...

  8. C语言范例学习04

    第三章 算法 前言:许多人对算法的看法是截然不同的,我之前提到过了.不过,我要说的还是那句话:算法体现编程思想,编程思想指引算法. 同时,有许多人认为简单算法都太简单了,应当去学习一些更为实用的复杂算 ...

  9. Google 面试

    坚持完成这套学习手册,你就可以去 Google 面试了 系统 指针 value Google 面试 阅读10266   本文为掘金投稿,译文出自:掘金翻译计划 原文地址:Google Intervie ...

随机推荐

  1. CentOS 7 Sersync+Rsync 实现数据文件实时同步

    rsync+inotify-tools与rsync+sersync架构的区别? 1.rsync+inotify-tools inotify只能记录下被监听的目录发生了变化(增,删,改)并没有把具体是哪 ...

  2. Python之socket_udp

    UDP服务端&客户端编程 ''' udp编程 创建socket对象,socket.SOCK_DGRAM 绑定ip和port,bind()方法 传输数据 1.接收数据,socket.recvfr ...

  3. C#-----线程安全的ConcurrentQueue<T>队列

     ConcurrentQueue<T>队列是一个高效的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据 ...

  4. pycharm 打开json 文件 \2 自动成了转义字符

    打开json 文件 \2 自动成了转义字符 暂时只发现在( \2 ) \ 后面为数字的情况下会出现转义json 文件为是指:在pycharm 中新建 file 后缀为json的文件 如: 1234.j ...

  5. Qt3D Shader

    --------------------------------------------------- Qt3D ShaderPrograme Qt3D GLSL 渲染器 Shader示例可参考: h ...

  6. Centos7 创建内部的yum源

  7. getparameter的使用

    在做项目的过程中,会遇到跳转的页面,直接打开到里面的子项,这个时候,看了UI给我设计了四个页面,如果做四个页面,肯定是可以实现的.但是这个不符合前端的设计.就在想通过点击传值进去,肯定是能够获取到的. ...

  8. Gradle's dependency cache may be corrupt

    原因分析: 当前Android studio 安装或者升级后配置的Gradle版本不对.可以打开安装目录下\Android\Android Studio\gradle\查看当前已有最新的版本.例如下图 ...

  9. c++算法实现(一) - 递归和初始化

    递归 写递归函数经常出错,提醒自己两个规则: 1. 一般来说递归函数中不应该出现for.while之类的循环语句, 因为递归就是循环的另外一种实现: 2. 注意基线条件,具体参考<算法图解> ...

  10. python timeit模块

    timeit模块timeit模块可以用来测试一小段Python代码的执行速度. class timeit.Timer(stmt='pass', setup='pass', timer=<time ...