heap_sort
(from wikipedia)
构建步骤:
- 建成一个大顶堆
- 第一个元素依次和最后一个元素交换,由于交换后新的堆顶元素可能违反大根堆的性质,因此需要对当前无序区(1,2,...,n-1)调整为新堆
- 不断重复此过程直到有序区的元素个数为n-1
- 排序完成
下面举例说明:
给定一个列表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的更多相关文章
- 堆排序Heap_Sort
堆排序就是借助二叉堆进行排序,不了解二叉堆的可以先看这里.本文以升序排序为例,首先将待排序数组放置在最小堆中,此时堆顶一定是数组中最小的元素,然后删除堆顶元素,此时调整后的最小堆顶会是第二小的元素,从 ...
- [数据结构]——堆(Heap)、堆排序和TopK
堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...
- 七种机器内部排序的原理与C语言实现,并计算它们的比较次数与移动次数。
内部排序是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列. 排序是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列.排序分为 ...
- 基于python的七种经典排序算法
参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...
- 基本排序算法的Python实现
本篇主要实现九(八)大排序算法,分别是冒泡排序,插入排序,选择排序,希尔排序,归并排序,快速排序,堆排序,计数排序.希望大家回顾知识的时候也能从我的这篇文章得到帮助. 为了防止误导读者,本文所有概念性 ...
- leetcode bugfree note
463. Island Perimeterhttps://leetcode.com/problems/island-perimeter/就是逐一遍历所有的cell,用分离的cell总的的边数减去重叠的 ...
- Python学习路程day17
常用算法与设计模式 选择排序 时间复杂度 二.计算方法 1.一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费 ...
- C语言范例学习04
第三章 算法 前言:许多人对算法的看法是截然不同的,我之前提到过了.不过,我要说的还是那句话:算法体现编程思想,编程思想指引算法. 同时,有许多人认为简单算法都太简单了,应当去学习一些更为实用的复杂算 ...
- Google 面试
坚持完成这套学习手册,你就可以去 Google 面试了 系统 指针 value Google 面试 阅读10266 本文为掘金投稿,译文出自:掘金翻译计划 原文地址:Google Intervie ...
随机推荐
- iOS 字体下载
iOS可以动态的为系统下载字体,这些字体都下载到了系统的目录下,并且可以被其他应用公用 来看下如何实现动态下载: // 创建下载字体请求描述的准备 NSMutableDictionary *attrs ...
- Hello greenDAO(SQLite)
一.配置Gradle Scripts: 1.1.build.gradle(Project:*****) buildscript { repositories { google() jcenter() ...
- Python 进阶 异步async/await
一,前言 本文将会讲述Python 3.5之后出现的async/await的使用方法,我从上看到一篇不错的博客,自己对其进行了梳理.该文章原地址https://www.cnblogs.com/dhcn ...
- .NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理?(转)
.NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理? 后端开发 作者: Rector 1973 阅读 0 评论 0 收藏 收藏本文 ...
- Leetcode: Sliding Window Median
Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...
- linux----------fedora 27 如何启用输入法
1.安装完成以后是自带了输入法的,但是需要启用. 一定要放到第一个位置,然后注销或者重启.
- 接口自动化测试持续集成--SoapUI安装
实际使用: 接口自动化测试持续集成框架:maven+SoapUI+jenkins 1.SoapUI安装文件下载5.1.2 http://pan.baidu.com/s/1c17dJLu安装步骤非常简单 ...
- 如何正确对用户密码进行加密?转自https://blog.csdn.net/zhouyan8603/article/details/80473083
本文介绍了对密码哈希加密的基础知识,以及什么是正确的加密方式.还介绍了常见的密码破解方法,给出了如何避免密码被破解的思路.相信读者阅读本文后,就会对密码的加密有一个正确的认识,并对密码正确进行加密措施 ...
- js闭包讲解
今日看到之前写的一段js代码,关于导航部分鼠标放上去变类,鼠标离开等效果 前端代码 <div class="con12"> <div class="le ...
- uva 10123 - No Tipping dp 记忆化搜索
这题的题意是 在双脚天平上有N块东西,依次从上面取走一些,最后使得这个天平保持平衡! 解题: 逆着来依次放入,如果可行那就可以,记得得有木板自身的重量. /********************** ...