(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. Java面试题和解答(四)

    1.JVM什么情况下会GC,GC策略有哪些 当应用程序分配新的对象,GC的代的预算大小已经达到阈值,比如GC的第0代已满:代码主动显式调用System.GC.Collect():其他特殊情况,比如,系 ...

  2. (转)Centos下,Docker部署Yapi接口管理平台

    接口测试的工具很多,公司引进了接口管理平台Yapi,自己尝试直接搭建,从安装Nodejs到配置MongoDB数据库,再到安装yapi的时候,遇到浏览器打开本地服务器Ip地址后,没有显示部署内容...没 ...

  3. webclient 操作超时

    Client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/ ...

  4. .NET 内存分配笔记

    阅读博客http://jonskeet.uk/csharp/memory.html的笔记(个人水平有限,如若翻译.记录有误,请提,谢谢~) 误区:引用类型保持在堆中,值类型保持在栈中. 问题:前半句正 ...

  5. unity组件路径自动生成

    unity 有时候找路径太麻烦 写了一个自动生成脚本的工具 using System.Collections.Generic; using System.IO; using System.Text; ...

  6. MQ消息队列配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. ubuntu16.04 backup and restore

    http://blog.csdn.net/qq_35523593/article/details/78545530

  8. day14 python各种推导式详解

    推导式的套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. variabl ...

  9. python安装pip的步骤记录

    因为重新装了系统,所以python所有的环境都要重新走一遍. 首先去python官网下载python最新版本.如果python没有自动加入环境变量的话就需要你自己手动加入.这个一般在安装python的 ...

  10. Excel控制AutoCad进行坐标标注

    做过工程测绘,平面设计,使用过Autocad制图的朋友们,都经常要在CAD上标注点或者线的坐标,CAD自身的标注功能,并不能同时标注X和Y坐标,,要同时标注X和Y坐标,可以使用南方CASS软件,或者一 ...