算法与数据结构——堆排序

news/2024/10/20 21:10:56

堆排序

堆排序(heap sort)是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序。

  • 输入数组并建立小顶堆,此时最小元素位于堆顶。
  • 不断执行出堆操作,依次记录出堆元素,即可得到从小到大排序的序列。

以上方法虽然可行,但需借助一个额外数组来保存弹出的元素,比较浪费空间。在实际中,我们通常使用一种更加优雅的实现方式。

算法流程

设数组长度为n,对排序流程如下所示。

  1. 输入数组并建立大顶堆。完成后,最大元素位于堆顶。
  2. 将堆顶元素(第一个元素)与堆底元素(最后一个元素)交换。完成交换后,堆的长度减1,已排序元素数量加1。
  3. 从堆顶元素开始,从顶至底执行堆化操作(sift down)。完成堆化后,堆的性质得到修复。
  4. 循环执行第2.步和第3.步。循环n-1轮后,即可完成数组排序。






在代码实现中,我们使用了与“堆”相同的从顶至底堆化sift_down()函数。值得注意的是,由于堆的长度会随着提取最大元素而减小,因此我们需要给sift_down()函数添加一个长度参数n,用于指定堆的当前有效长度。

#include "iostream"
#include "vector"
using namespace std;
/*从顶至底堆化*/
void sift_down(vector<int> &nums, int n, int i){while (true){// 判断节点 i, l, r 中值最大的节点,记为 maint l = 2 * i + 1;int r = 2 * i + 2;int ma = i;if (l < n  && nums[l] > nums[ma]){ma = l;}if (r < n &&nums[r] > nums[ma]){ma = r;}// 若节点 i 最大或索引 l, r 越界,则无须继续堆化,跳出if (ma == i) break;// 交换两节点swap(nums[i], nums[ma]);// 循环向下堆化i = ma;}}
/*堆排序*/
void heap_sort(vector<int> &nums){// 建堆操作:堆化除叶节点之外的其他所有节点for (int i = nums.size() / 2 - 1; i >= 0; --i){sift_down(nums, nums.size(), i);}// 从堆中提取最大元素,循环 n - 1 轮for (int i = nums.size() - 1; i > 0; --i){// 交换根节点与最右叶节点(交换首元素与尾元素)swap(nums[0], nums[i]);// 以根节点为起点,从顶至底进行堆化sift_down(nums, i, 0);}
}
int main(){vector<int> nums = { 12, 33, 5, 4, 66, 7, 2 };heap_sort(nums);for (int num : nums){cout << num << " ";}cout << endl;system("pause");return 0;
}

算法特性

  • 时间复杂度为O(nlogn)、非自适应排序:建堆操作使用O(n)时间。从堆中提取最大元素的时间复杂度为O(logn),总共循环n-1轮。
  • 空间复杂度为O(1)、原地排序:几个指针变量使用O(1)空间。元素交换和堆化操作都是在原数组上进行的。
  • 非稳定排序:在交换堆顶元素和堆底元素时,相等元素的相对位置可能发生变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/72580.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

ZBrush和3D-Coat各自的优缺点是什么?

zbrush支持的模型面数高英文界面,3d coat支持的模型面数比zbrsh低有中文界 ZBrush优缺点1、ZBrush优点: zbrush是高精度建模poser制作的首选。可搭配雕刻版使用,主要为烘焙高细节的铁图建模。因为是高精度模型,不适用于动画和游戏制作,所以建模师普遍用它来制作贴图,辅助…

24. 两两交换链表中的节点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例 1: 输入:head = [1,2,3,4] 输出:[2,1,4,3] 示例 2: 输入:head = [] 输出:[] 示例 3: 输入:head = [1] 输出:[1] 解题思…

Z函数(扩展KMP)

Z函数学习,Z数组和E数组的构建扩展KMP(Z函数) Z数组 简单理解 \(Z[i]\) 表示字符串从i出发,与整体相比有多长的公共前缀 a a a b a a c 7 2 1 0 2 1 0可以先理解马拉车再来看 首先,设置两个类似的东西,关键点 \(c\) 和最右边界 \(r\) ,表示 \(Z[c]\) 是目前所有 \(Z\) 中…

2024北森题库(含答案)

"2024北森题库(含答案)"揭示了这是一份针对教育和考试领域的资源,特别是与北森题库相关的练习题目和解答。北森题库通常指的是由北森公司提供的各类考试模拟题集,涵盖了诸多考试科目,如公务员考试、事业单位招聘、教师资格证考试等。这份资料对于备考者来说是一…

页面下拉刷新事件

启用下拉刷新 配置下拉刷新样式监听页面的下拉刷新事件 停止下拉刷新样式

2024 最新 jetbrains GoLand 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 GoLand 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!…

2024 最新 jetbrains DataGrip 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 IDEA 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!2.…

2024 最新 jetbrains WebStorm 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 IDEA 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!2.…