当前位置:网站首页>ACM教程 - 堆排序
ACM教程 - 堆排序
2022-06-11 00:45:00 【放羊的牧码】
定义
堆是一种叫做完全二叉树的数据结构。这里我们用到两种堆,其实也算是一种。
- 大顶堆:每个节点的值都大于或者等于它的左右子节点的值。
- 小顶堆:每个节点的值都小于或者等于它的左右子节点的值。
Ps:小顶堆有误,节点3 和 节点2 换下位置!
如上所示,就是两种堆。如果我们把这种逻辑结构映射到数组中,就是下边这样
| 9 | 5 | 8 | 2 | 3 | 4 | 7 | 1 |
| 1 | 2 | 5 | 4 | 3 | 8 | 9 | 7 |
这个数组 arr 逻辑上就是一个堆。从这里我们可以得出以下性质(重点)
- 对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
- 对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]
- 稳定性:根据 相等元素 在数组中的 相对顺序 是否被改变,排序算法可分为「稳定排序」和「非稳定排序」两类。
- 就地性:根据排序过程中 是否使用额外内存(辅助数组),排序算法可分为「原地排序」和「异地排序」两类。一般地,由于不使用外部内存,原地排序相比非原地排序的执行效率更高。
- 自适应性:根据算法 时间复杂度 是否 受待排序数组的元素分布影响 ,排序算法可分为「自适应排序」和「非自适应排序」两类。「自适应排序」的时间复杂度受元素分布影响,反之不受其影响。
- 比较类:比较类排序基于元素之间的 比较算子(小于、相等、大于)来决定元素的相对顺序;相对的,非比较排序则不基于比较算子实现。
图解

| 4 | 5 | 8 | 2 | 3 | 9 | 7 | 1 |
以该数组为例,构建最大堆实现从小到大排序,几个要点如下
- 一开始构建最大堆,从最后一个非叶子节点开始直到根节点进行自底向上(从下到上,从右到左)
- 轮到自己节点时(当前作为父节点来看待),分别比较自己的左子节点和右子节点,最终判断出最大的节点,如果最大节点是自己本身,不交换;否则自己节点和最大节点进行交换
- 如果第 2 点不存在交换(跳过第 3 点),否则继续将换下去的子节点(原本是父节点,没错吧),继续往下维护同样的比较操作,直到没有节点了为止

- 以上构建最大堆完毕,接下来开始真正的堆排序,第一次构建完,根节点一定是最大值,换到最后 1 个叶子节点,此时最后 1 个节点到了根节点,再进行维护堆,就又会产生第 2 个最大值,然后再次将该根节点交换到倒数第 2 个叶子节点,依此类推。完毕(因为篇幅有限,只罗列解释中关键几个中间过程图例)




性质
- 时间复杂度
- 最佳 O(nlogn)
- 平均 O(nlogn)
- 最差 O(nlogn)
- 空间复杂度
- 最差 O(1)
- 稳定性:不稳定
- 就地性:原地
- 自适应性:非自适应
- 比较类:比较
Java
public class HeapSort {
// 入口在这
public static void heapSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int len = arr.length;
// 构建大顶堆,这里其实就是把待排序序列,变成一个大顶堆结构的数组
buildMaxHeap(arr, len);
// 交换堆顶和当前末尾的节点,重置大顶堆
for (int i = len - 1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapify(arr, 0, len);
}
}
private static void buildMaxHeap(int[] arr, int len) {
// 从最后一个非叶节点开始向前遍历,调整节点性质,使之成为大顶堆
for (int i = (len - 1) / 2; i >= 0; i--) {
heapify(arr, i, len);
}
}
private static void heapify(int[] arr, int i, int len) {
// 先根据堆性质,找出它左右节点的索引
int left = 2 * i + 1;
int right = 2 * i + 2;
// 默认当前节点(父节点)是最大值。
int largestIndex = i;
if (left < len && arr[left] > arr[largestIndex]) {
// 如果有左节点,并且左节点的值更大,更新最大值的索引
largestIndex = left;
}
if (right < len && arr[right] > arr[largestIndex]) {
// 如果有右节点,并且右节点的值更大,更新最大值的索引
largestIndex = right;
}
if (largestIndex != i) {
// 如果最大值不是当前非叶子节点的值,那么就把当前节点和最大值的子节点值互换
swap(arr, i, largestIndex);
// 因为互换之后,子节点的值变了,如果该子节点也有自己的子节点,仍需要再次调整。
heapify(arr, largestIndex, len);
}
}
private static void swap (int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}边栏推荐
- EXJ形儿多眼前因断会满意接MBtXE
- ROS参数服务器
- 【HaaS Hands-On】全新视频节目上线 创意案例我们一起上手做 第一期E01: 物联网工程师 和你一起上手做遥控机械臂
- Matlab array other common operation notes
- 2021-02-03美赛前MATLAB的学习笔记(灰色预测、线性规划)
- LeetCode 1010 Pairs of Songs With Total Durations Divisible by 60 (hash)
- 2.0 detailed explanation of ROS and Px4 communication
- 面试官:介绍一下你简历中的项目,细讲一点,附项目实战
- 今日睡眠质量记录80分
- Role of handlermethodargumentresolver + use case
猜你喜欢

LeetCode 1609 Even Odd Tree (bfs)

Application of object storage S3 in distributed file system

1.3 introduction to ROS UAV
![[leetcode] delete duplicate Element II in the sorting linked list](/img/24/0f8e4a2d15732997c8eb8973669bf7.jpg)
[leetcode] delete duplicate Element II in the sorting linked list
![[ROS introduction] cmakelist Txt and packages XML interpretation](/img/26/bae82a457fb83b2214d2f8c20955e2.jpg)
[ROS introduction] cmakelist Txt and packages XML interpretation

From "0" to "tens of millions" concurrency, 14 technological innovations of Alibaba distributed architecture
![[path planning] week 1: hodgepodge](/img/80/074b847c6826b306318aeb9866a829.jpg)
[path planning] week 1: hodgepodge

flutter 状态管理

面试官:介绍一下你简历中的项目,细讲一点,附项目实战

Leetcode 2054 two best non overlapping events
随机推荐
ros缺包怎么办
Dialog AlertDialog 、SimpleDialog、showModalBottomSheet、showToast Flutter 自定义 Dialog
Loki 学习总结(1)—— Loki 中小项目日志系统的不二之选
视频压缩数据集TVD
1.3 introduction to ROS UAV
Summary of SAS final review knowledge points (notes on Application of multivariate statistics experiment)
2022.6.6-----leetcode.732
2.2、ROS+PX4仿真多点巡航飞行----正方形
关于概率统计中的排列组合
The argument type ‘int?‘ can‘t be assigned to the parameter type ‘num‘
Px4 installation tutorial (VI) vertical fixed wing (tilting)
2021-2-14 gephi learning notes
Leetcode 430 flat a multilevel double linked list (DFS linked list)
2021-02-27MATLAB的图像处理
Matlab random function summary
关于CS-3120舵机使用过程中感觉反应慢的问题
[leetcode] reverse linked list
【图像处理】基于matlab GUI多功能图像处理系统【含Matlab源码 1876期】
[VBA Script] extract the information and pending status of all annotations in the word document
腾讯云数据库TDSQL-大咖论道 | 基础软件的过去、现在、未来