选择排序(2)——堆排序(heap sort)
前期概念:
二叉树 完全二叉树 左序遍历 中序遍历 右序遍历 堆 小根堆 大根堆
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
Heapify (A, i)
l← left [i]
r← right [i]
if l ≤ heap-size [A] and A[l] > A[i]
then largest ← l
else largest ← i
if r ≤ heap-size [A] and A[i] > A[largest]
then largest ← r
if largest ≠ i
then exchange A[i] ↔ A[largest]
Heapify (A, largest)
堆的概念
在介绍堆排序之前,首先需要说明一下,堆是个什么玩意儿。
堆是一棵顺序存储的完全二叉树。
其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。
其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。
举例来说,对于n个元素的序列{R0, R1, ... , Rn}当且仅当满足下列关系之一时,称之为堆:
(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)
(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
其中i=1,2,…,n/2向下取整;
要点:
首先,按堆的定义将数组R[0..n]调整为堆(这个过程称为创建初始堆),交换R[0]和R[n];
然后,将R[0..n-1]调整为堆,交换R[0]和R[n-1];
如此反复,直到交换了R[0]和R[1]为止。
以上思想可归纳为两个操作:
(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。
(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。
当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。
先通过详细的实例图来看一下,如何构建初始堆。
—————————————————————————————————————————————————————
//代码
public class HeapSort {
private static int[] sort = new int[] { 1, 0, 10, 20, 3, 5, 6, 4, 9, 8, 12, 17, 34, 11 };
public static void main(String[] args) {
System.out.println("Before sort: " + Arrays.toString(sort));
// 没有子节点的才需要创建最大堆,从最后一个的父节点开始
int startIndex = ((sort.length - 1) - 1) >> 1;
// 从尾端开始创建最大堆,每次都是正确的堆
for (int i = startIndex; i >= 0; i--) {
maxHeapify(sort, sort.length, i);
}
// 排序,最大值放在末尾,data虽然是最大堆,在排序后就成了递增的
// 末尾与头交换,交换后调整最大堆
for (int i = sort.length - 1; i > 0; i--) {
int temp = sort[0];
sort[0] = sort[i];
sort[i] = temp;
maxHeapify(sort, i, 0);
}
System.out.println("After Heapsort : " + Arrays.toString(sort));
}
/**
创建最大堆
*/
private static void maxHeapify(int[] data, int heapSize, int index) {
// 当前点与左右子节点比较
int left = (index << 1) + 1;
int right = (index << 1) + 2;int largest = index;
if (left < heapSize && data[index] < data[left]) {
largest = left;
}
if (right < heapSize && data[largest] < data[right]) {
largest = right;
}
// 得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整
if (largest != index) {
int temp = data[index];
data[index] = data[largest];
data[largest] = temp;
maxHeapify(data, heapSize, largest);
}
}
}
//// end
备注:
参考链接地址:https://wenku.baidu.com/view/af5705ea856a561252d36f71.html
选择排序(2)——堆排序(heap sort)的更多相关文章
- [译]async/await中使用阻塞式代码导致死锁 百万数据排序:优化的选择排序(堆排序)
[译]async/await中使用阻塞式代码导致死锁 这篇博文主要是讲解在async/await中使用阻塞式代码导致死锁的问题,以及如何避免出现这种死锁.内容主要是从作者Stephen Cleary的 ...
- Python入门篇-数据结构堆排序Heap Sort
Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...
- 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)
堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
- 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)
不多说,直接上干货! 插入排序包括直接插入排序.希尔排序. 1.直接插入排序: 如何写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用 ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- 直接选择排序(Straight Selection Sort)
1.定义 选择排序(Selection Sort)的基本思想是:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕. 常用的选择排序方法有直接选择排序和堆 ...
- 简单选择排序(Simple Selection Sort)的C语言实现
简单选择排序(Simple Selection Sort)的核心思想是每次选择无序序列最小的数放在有序序列最后 演示实例: C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 原创文章, ...
- 八大排序算法之三选择排序—简单选择排序(Simple Selection Sort)
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
随机推荐
- 日常开发需要掌握的Maven知识
文章来自:https://www.jianshu.com/p/e224a6dc8f20和https://www.jianshu.com/p/20b39ab6a88c Maven出现之前 jar包默认都 ...
- ThinkPHP---案例--实现知识管理功能
[一]准备工作 (1)数据表sp_knowledge SQL语句:知识管理数据表结构 create table sp_knowledge( id int(11) not null auto_incre ...
- php第二十四节课
三级联动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- 网络基础——OSI参考模型
一.OSI/ISO/IOS傻傻分不清楚 ISO 国际标准化组织(International Organization for Standardization)简称ISO,是一个全球性的非政府组织,是国 ...
- 利用python去调用shell命令时候的踩到的坑
shell中 True的返回值是0 False的返回值是1 Python中 True的返回值是1 False的返回值是0
- 2018百度之星资格赛T2 子串查询
[题解] 很容易想到暴力做法:对于每个询问暴力查找区间内的最小字母,统计其出现次数.效率O(N^2),无法通过全部数据. 我们可以换一个思路,设f[i][j]为第i个字母(字母‘A'到’Z'分别对应0 ...
- Placing Lampposts
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=91212#problem/E #include <iostream> #inc ...
- 【Codeforces 582A】GCD Table
[链接] 我是链接,点我呀:) [题意] 给你一个数组A[]经过a[i][j] = gcd(A[i],A[j])的规则生成的二维数组 让你求出原数组A [题解] 我们假设原数组是A 然后让A数组满足A ...
- excel 2003 默认保存后出现超级连接解决方法
在excel 2003 中当选中某个单元格然后拷贝出来后发现总是出现超级连接,每次都要取消下很是麻烦 . 于是经过研究找到解决方法,真是累的我够呛 ,先将方法介绍给大家. 工具---自动更正选项--- ...
- [luoguP2387] 魔法森林(LCT + 并查集)
传送门 并查集真是一个判断连通的好东西! 连通性用并查集来搞. 把每一条边按照 a 为关键字从小到大排序. 那么直接枚举,动态维护 b 的最小生成树 用 a[i] + 1 ~ n 路径上最大的 b[i ...