堆排序(C++实现)
参考:
- 面试官:请写一个堆排序_哔哩哔哩_bilibili
- C++实现排序算法_c++从小到大排序-CSDN博客
堆的基本概念
-
堆排实际上是利用堆的性质来进行排序。堆可以看做一颗完全二叉树。
-
堆分为两类:
- 最大堆(大顶堆):除根节点外,堆的每个父节点都大于其孩子节点。
- 最小堆(小顶堆):除根节点外,堆的每个父节点都小于其孩子节点。
- 最大堆和最小堆示意图:
-
数据结构包含逻辑结构和存储结构,对于堆来说:
- 堆的逻辑结构是完全二叉树
- 堆的存储结构可以是链式存储,也可以是顺序存储。在堆排序中我们基于的存储结构是顺序存储。
- 顺序存储示意图:(以最大堆为例)
堆排序
- 堆排序主要分为三个步骤:
- 建堆
- 交换数据
- 重复步骤1,2
- 建堆。首先说说建堆,因为我们要对数组进行排序,这个数组里元素原本的排列是无规则的,为了能通过堆对数组进行排序,我们需要进行“建堆”操作,从而使得数组的排序符合堆的要求。根据上文可知,堆可以分为两种,一种是最大堆,另一种是最小堆。既然有两种堆,我们应该基于哪种类别来建堆呢?这就要取决于我们的排序形式了,如果是升序(从小到大),则需要建最大堆;如果是降序(从大到小),则需要建最小堆。以下都以升序(建最大堆为例)。
- 交换数据。交换什么数据呢?这里直接给出结论,是交换堆(数组)索引为0的元素和末尾元素(堆的最后一个元素)。因为我们已经建好堆了,且我们堆的存储结构是顺序结构,即根节点(只最大的节点)存储在数组的第一位(索引为0),这是我们将这个数与数组最后一个数交换位置,就完成了数组中最大元素的排序(因为最大的元素肯定在数组最后一个位置)。
- 交换完数据后,对于新的堆(新的二叉树)来说,是不满足最大堆的条件的(因为发生了位置交换),这时就需要重新建堆,重新建堆有别于初次建堆,因为我们已经固定了最大元素的位置,所以之后建堆不应该让这个最大的元素参与进来。
- 参考代码如下:
最大堆建堆:
/*** 堆化* 大根堆(大顶堆/最大堆),小的数往下沉*/
void maxHeapify(vector<int> &nums, int pos, int len)
{// (pos << 1) + 1就是2*pos+1,对应该节点的左子节点// (pos << 1) + 2就是2*pos+2,对应该节点的右子节点int child = (pos << 1) + 1;while (child < len){if (child + 1 < len && nums[child + 1] > nums[child]){child = child + 1;}if (nums[pos] > nums[child]){return;}else{swap(nums[pos], nums[child]);pos = child;child = (pos << 1) + 1;}}
}
最小堆建堆:
/*** 堆化* 小根堆(小顶堆/最小堆),大的数往下沉*/
void minHeapify(vector<int> &nums, int pos, int len)
{// (pos << 1) + 1就是2*pos+1,对应该节点的左子节点// (pos << 1) + 2就是2*pos+2,对应该节点的右子节点int child = (pos << 1) + 1;while (child < len){if (child + 1 < len && nums[child + 1] < nums[child]){child = child + 1;}if (nums[pos] < nums[child]){return;}else{swap(nums[pos], nums[child]);pos = child;child = (pos << 1) + 1;}}
}
堆排序:
/*** 堆排序*/
void heapSort(vector<int> &nums)
{// 每次交换完数据后要len--,让排序好的元素不参与建堆for (int len = nums.size(); len > 0; len--){// (len - 2) >> 1就是(len-2)/2,这样能找到最后一个非叶子结点for (int i = (len - 2) >> 1; i >= 0; i--){minHeapify(nums, i, len);// 最小堆建堆,对应降序// maxHeapify(nums, i, len);// 最大堆建堆,对应升序}// 每进行一次交换就要重新堆化,且重新堆化时堆的大小要对应减1(因为堆末尾的元素已经排好序了)swap(nums[0], nums[len - 1]);}
}
堆排序测试用例
#include <iostream>
#include <vector>using namespace std;/*** 堆化* 大根堆(大顶堆/最大堆),小的数往下沉*/
void maxHeapify(vector<int> &nums, int pos, int len)
{int child = (pos << 1) + 1;while (child < len){if (child + 1 < len && nums[child + 1] > nums[child]){child = child + 1;}if (nums[pos] > nums[child]){return;}else{swap(nums[pos], nums[child]);pos = child;child = (pos << 1) + 1;}}
}/*** 堆化* 小根堆(小顶堆/最小堆),大的数往下沉*/
void minHeapify(vector<int> &nums, int pos, int len)
{int child = (pos << 1) + 1;while (child < len){if (child + 1 < len && nums[child + 1] < nums[child]){child = child + 1;}if (nums[pos] < nums[child]){return;}else{swap(nums[pos], nums[child]);pos = child;child = (pos << 1) + 1;}}
}/*** 堆排序*/
void heapSort(vector<int> &nums)
{for (int len = nums.size(); len > 0; len--){for (int i = (len - 2) >> 1; i >= 0; i--){minHeapify(nums, i, len);// 最小堆建堆,对应降序// maxHeapify(nums, i, len);// 最大堆建堆,对应升序}// 每进行一次交换就要重新堆化,且重新堆化时堆的大小要对应减1(因为堆末尾的元素已经排好序了)swap(nums[0], nums[len - 1]);}
}int main(int argc, char const *argv[])
{vector<int> nums = {5, 3, 2, 63, 56, 8, -1, 3, 0, -222};heapSort(nums);for (auto num : nums){cout << num << " ";}cout << endl;return 0;
}
相关文章:

堆排序(C++实现)
参考: 面试官:请写一个堆排序_哔哩哔哩_bilibiliC实现排序算法_c从小到大排序-CSDN博客 堆的基本概念 堆排实际上是利用堆的性质来进行排序。堆可以看做一颗完全二叉树。 堆分为两类: 最大堆(大顶堆):除根…...
Qt中加入UI文件
将 UI 文件整合到 Qt 项目 使用 Qt Designer 创建 UI 文件: 在 Qt Creator 中使用 Qt Designer 创建 UI 文件,设计所需的界面。确保在设计中包含所需的控件(如按钮、文本框等),并为每个控件设置明确的对象名称…...
Redisson使用全解
redisson使用全解——redisson官方文档注释(上篇)_redisson官网中文-CSDN博客 redisson使用全解——redisson官方文档注释(中篇)-CSDN博客 redisson使用全解——redisson官方文档注释(下篇)_redisson官网…...
Go4 和对 Go 的贡献
本篇内容是根据2017年4月份Go4 and Contributing to Go音频录制内容的整理与翻译, Brad Fitzpatrick 加入节目谈论成为开源 Go 的代言人、让社区参与 bug 分类、Go 的潜在未来以及其他有趣的 Go 项目和新闻。 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. Erik St…...
区间动态规划
区间动态规划(Interval DP)是动态规划的一种重要变种,特别适用于解决一类具有区间性质的问题。典型的应用场景是给定一个区间,要求我们在满足某些条件下进行最优划分或合并。本文将从区间DP的基本思想、常见问题模型以及算法实现几…...

什么情况下需要使用电压探头
高压探头是一种专门设计用于测量高压电路或设备的探头,其作用是在电路测试和测量中提供安全、准确的信号捕获,并确保操作人员的安全。这些探头通常用于测量高压电源、变压器、电力系统、医疗设备以及其他需要处理高电压的设备或系统。 而高压差分探头差分…...
数据结构——八大排序(下)
数据结构中的八大排序算法是计算机科学领域经典的排序方法,它们各自具有不同的特点和适用场景。以下是这八大排序算法的详细介绍: 五、选择排序(Selection Sort) 核心思想:每一轮从未排序的元素中选择最小࿰…...

Linux系统:Ubuntu上安装Chrome浏览器
Ubuntu系统版本:23.04 在Ubuntu系统上安装Google Chrome浏览器,可以通过以下步骤进行: 终端输入以下命令,先更新软件源: sudo apt update 或 sudo apt upgrade终端输入以下命令,下载最新的Google Chrome .…...
Redis位图BitMap
一、为什么使用位图? 使用位图能有效实现 用户签到 等行为,用数据库表记录签到,将占用很多存储;但使用 位图BitMap,就能 大大减少存储占用 二、关于位图 本质上是String类型,最小长度8位(一个字…...
YOLOv11改进策略【卷积层】| ParNet 即插即用模块 二次创新C3k2
一、本文介绍 本文记录的是利用ParNet中的基础模块优化YOLOv11的目标检测网络模型。 ParNet block是一个即插即用模块,能够在不增加深度的情况下增加感受野,更好地处理图像中的不同尺度特征,有助于网络对输入数据更全面地理解和学习,从而提升网络的特征提取能力和分类性能…...

学习threejs,网格深度材质MeshDepthMaterial
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️网格深度材质MeshDepthMate…...

算法时间、空间复杂度(二)
目录 大O渐进表示法 一、时间复杂度量级的判断 定义: 例一:执行2*N+1次 例二:执行MN次 例三:执行已知次数 例四:存在最好情况和最坏情况 顺序查找 冒泡排序 二分查找 例五:阶乘递归 编辑 例…...
高级java每日一道面试题-2024年10月11日-数据库篇[Redis篇]-Redis都有哪些使用场景?
如果有遗漏,评论区告诉我进行补充 面试官: Redis都有哪些使用场景? 我回答: Redis 是一个开源的、基于键值对的数据结构存储系统,,它支持多种数据类型,包括字符串、散列、列表、集合和有序集合。它可以用作数据库、缓存和消息中间件。由于…...
0047__【python打包分发工具】setuptools详解
【python打包分发工具】setuptools详解-CSDN博客...
自定义拦截器处理token
目录 1、WebConfig 配置类 2、TSUserContext 把用户信息放到context中 3、自定义拦截器 4、在controller中可以使用 5、参考链接 1、WebConfig 配置类 @Configuration public class WebConfig implements WebMvcConfigurer {@Autowiredprivate AccessControlInterceptor …...

Scrapy | 使用Scrapy进行数据建模和请求
scrapy数据建模与请求 数据建模1.1 为什么建模1.2 如何建模1.3如何使用模板类1.4 开发流程总结 目标: 1.应用在scrapy项目中进行建模 2.应用构造Request对象,并发送请求 3.应用利用meta参数在不同的解析函数中传递数据 数据建模 | 通常在做项目的过程中…...

学习笔记——交换——STP(生成树)基本概念
三、基本概念 1、桥ID/网桥ID (Bridege ID,BID) 每一台运行STP的交换机都拥有一个唯一的桥ID(BID),BID(Bridge ID/桥ID)。在STP里我们使用不同的桥ID标识不同的交换机。 (2)BID(桥ID)组成 BID(桥ID)组成(8个字节):由16位(2字节)的桥优先级…...

机器学习笔记-2
文章目录 一、Linear model二、How to represent this function三、Function with unknown parameter四、ReLU总结、A fancy name 一、Linear model 线性模型过于简单,有很大限制,我们需要更多复杂模式 蓝色是线性模型,线性模型无法去表示…...

SpringSecurity(一)——认证实现
一、初步理解 SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器。 当前系统中SpringSecurity过滤器链中有哪些过滤器及它们的顺序。 核心过滤器: (认证)UsernamePasswordAuthenticationFilter:负责处理…...

VMWare NAT 模式下 虚拟机上不了网原因排查
vmware 按照了Linux之后 无法上网,搞定后,记录一些信息。 window有两个虚拟网卡 VMnet1 对应的是 Host-Only(仅主机模式) VMnet8 对应的是 NAT(网络地址转换模式) 在NAT模式中,需要设置NAT和D…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...