排序算法(七)-堆排序
来源:互联网 发布:提取网页数据到excel 编辑:程序博客网 时间:2024/06/08 13:20
1. 原理
1.1 什么是堆
要理解堆排序,首先要先理解什么是堆。堆是一颗顺序存储的完全二叉树,堆又分为最大堆和最小堆。
- 完全二叉树:设二叉树的深度为h,除h层外,其他各层的节点数都达到最大个数,第h层的所有节点都连续集中在最左边。
- 最小堆:每个节点的值都不大于其子节点的值的完全二叉树
- 最小堆:每个节点的值都不小于其子节点的值的完全二叉树
根据上面的描述我们可以用一个数学描述来定义最大最小堆:
对于数组[D(0), D(1), …., D(n)]当且仅当满足下列关系时称之为堆
- 最小堆:D(i) <= D(2 * i + 1)并且D(i) <= D(2 * i + 2)
- 最大堆:D(i) >= D(2 * i + 1)并且D(i) >= D(2 * i + 2)
- 其中整数i = 0, 1, 2, …, n/2
举个栗子:[3, 4, 7, 12, 15, 18]就是一个典型的最小堆, i <= 2。
- i取0时:3 > 4, 3 > 4
- i取1时:4 > 12, 4 > 15
- i取2时:7 > 18
1.2 堆排序
理解了堆的概念之后,堆排序就是利用最大堆和最小堆的特性进行排序
- 将数组初始化成最大堆
- 交换最大堆的第一个和最后一个数字,输出最后一个数字(最大值)
- 将破坏后的最大堆重新调整为最大堆
- 接着重复2~3步直到交换堆的第一和第二个节点,此时结束排序
2. 实现
此算法的关键在于如何构建最大堆。根据上诉最大最小堆的定义,可以写出针对某一parent的调整算法。
public void adjustMaxHeap(int[] data, int parent, int length) { int temp = data[parent]; int child = 2 * parent + 1; while (child < length) { //如有有右子节点,并且右子节点大于左子节点,则选取右子节点和parent比较 if (child + 1 < length && data[child] < data[child + 1]) { child++; } //如果父节点的值大于子节点的值,则跳出循环 if (temp >= data[child]) { break; } //把孩子节点的值赋给父节点 data[parent] = data[child]; //选取子节点的左子节点,继续向下调整 parent = child; child = 2 * child + 1; } data[parent] = temp;}
此函数为调整某个parent的值,初始化的时候需要从n/2开始一直循环调整到0;
for (int i = data.length / 2; i >= 0; i--) { adjustMaxHeap(data, i);}
完整对堆排序算法如下:
@Overridepublic int[] sort(int[] data) { if (data == null || data.length <= 1) { return data; } for (int i = data.length / 2; i >= 0; i--) { adjustMaxHeap(data, i, data.length); } for (int i = data.length - 1; i > 0; i--) { //最后一个数字和第一个数字交换 swap(data, 0, i); //由于parent=0的节点发生了变化,因此需要重新调整堆 adjustMaxHeap(data, 0, i); } return data;}
完整实现可查看:
GitHub/HeapSort
3. 复杂度
堆排序是一种不稳定的排序算法。平均,最坏和最好的时间复杂度都是O(nlogn)。
阅读全文
0 0
- 排序算法(七)-堆排序
- 排序算法(七) 堆排序
- 排序算法七:选择排序之堆排序
- 排序算法七:选择排序之堆排序
- 基于JAVA的排序算法之七--堆排序
- 排序算法(七)——堆排序
- 排序算法(七)——堆排序
- 排序算法(七):JAVA实现堆排序
- 排序算法(七)——堆排序
- 排序七之堆排序
- 七种排序算法,包括:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 白话经典算法系列之七 堆与堆排序
- 基于OpenCV的简易四肢位置识别与动作识别
- Min Stack 最小栈
- 八、JDBC——分页查询(mysql的limit方法)
- 高质量深度学习资源总结:128篇论文,21大领域
- bzoj 1878(莫队)(主席树)
- 排序算法(七)-堆排序
- 代理服务器的原理,代理服务器和vpn的区别
- Maven搭建SSH案例(二)-----SSH框架在maven中的配置
- 2016年,某猎头给我的面试准备资料
- 排序算法(八)-基数排序
- OGNL基本使用
- 《推拿》
- 工程中js代码小技巧
- 机器学习第一章:python数据处理与可视化