当前位置: 首页 > news >正文

堆排序详细理解

目录

一、前备知识

二、建堆

2.2.1 向上调整算法建堆

2.2.2 向下调整算法建堆

三、排序

3.1 常见问题 

3.2 思路

3.3 源码


一、前备知识

详细图解请点击:二叉树的顺序实现-堆-CSDN博客

本文只附上向上/向下调整算法的源码

//交换
void Swap(int* p, int* q)
{int tmp = *p;*p = *q;*q = tmp;
}
//向下调整算法
void AdjustDown(int* a, int n, int parent)
{//左孩子的下标int child = parent * 2 + 1;while (child<n){//找到两个孩子中较小的孩子-假设法if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[parent] > a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}
//向上调整算法
void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

二、建堆

堆排序堆排序,先有堆才能排序,所以排序的第一步是要将一个一般的数组建成堆。

注:由于建大堆还是小堆仅仅取决于自定的大小于号,本文下述建堆都以小堆为例

2.2.1 向上调整算法建堆

思路:

  1. 单一的一个结点可以看成一个堆
  2. 后续的所有结点都可以看作是插入结点

所以只需要循环插入所有后续结点即可

void BuildHeap1(int* a, int n)
{//把根节点看作是堆,剩下的结点看作插入结点,开始依次插入for (int i = 1; i < n; i++){AdjustUp(a, i);}
}

2.2.2 向下调整算法建堆

错误思路:

向下调整算法要求左右子树必须为大/小堆,所以从根节点开始结点开始建堆的做法是错误的

正确思路:

上文说:单一的一个结点可以看成一个堆所以从最后一个叶子节点的父节点开始向下调整,不断循环所有父节点,就可以保证他的左右子树都是堆。

void BuildHeap2(int* a, int n)
{//从最后一个叶子结点的父结点开始调for (int i = ((n - 1) - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}
}

三、排序

3.1 常见问题 

  • 为什么建堆后依然还要排序?

        大堆/小堆的定义注定了堆仅仅能保证父节点大于孩子结点,无法保证孩子结点按照大于/小于的次序严格排列!!!

  • 升序建小堆,降序建大堆的思路是否可行?
  1. 升序建小堆:首先对 n 个数建小堆,选出最小的数,接着对剩下的 n-1 个数建小堆,选出第二小的数,不断重复上述过程。若用向上调整算法可行但时间复杂度太高,若使用向下调整算法时,对n-1个调整就会发现:原先的孩子父亲关系全乱,不可行。
  2. 降序建大堆:首先对 n 个数建小堆,选出最小的数,接着对剩下的 n-1 个数建大堆,选出第二大的数,不断重复上述过程。使用向下调整算法时,对n-1个调整就会发现:原先的孩子父亲关系全乱,不可行。

3.2 思路

  1. 本质上是堆删除的思路。利用堆的特性,无论是大堆还是小堆,根节点的值一定是最大/小的数。这样每进行一次调整,就会选择出最小/大,次小/大......便可以实现排序。
  2. 为了防止出现父子关系乱序的问题,将每次找到的最值放在堆的末位置,对前n-1个元素进行向下调整,便可以完美解决排序问题
  3. 由此可以总结:升序建大堆,降序建小堆

由此,我们可以归纳出堆排序算法的步骤:

1. 把无序数组构建成二叉堆。

2. 循环删除堆顶元素,移到数组尾部,调节堆产生新的堆顶。

3.3 源码

//降序建小堆
void HeapSortDown(int* a, int n)
{//建小堆for (int i = ((n - 1) - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}//排序int end = n - 1;        //定位数组最后一个位置while (end > 0){Swap(&a[0], &a[end]);	// 将堆顶元素和堆中最后一个元素交换,把最大的数(堆顶)放到最后AdjustDown(a, end, 0);end--;					// 调整前n-1个元素}
}

相关文章:

堆排序详细理解

目录 一、前备知识 二、建堆 2.2.1 向上调整算法建堆 2.2.2 向下调整算法建堆 三、排序 3.1 常见问题 3.2 思路 3.3 源码 一、前备知识 详细图解请点击&#xff1a;二叉树的顺序实现-堆-CSDN博客 本文只附上向上/向下调整算法的源码 //交换 void Swap(int* p, int* …...

RK3588+FPGA+AI高性能边缘计算盒子,应用于视频分析、图像视觉等

搭载RK3588&#xff08;四核 A76四核 A55&#xff09;&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU运算能力&#xff0c;具备6T AI算力&#xff0c;可扩展至38T算力。 产品规格 系统主控CPURK3588&#xff0c;四核…...

07-操作元素(键盘和鼠标事件)

在前面的文章中重点介绍了一些元素的定位方法&#xff0c;定位到元素后&#xff0c;就需要操作元素了。本篇总结了web页面常用的一些操作元素方法&#xff0c;可以统称为行为事件。 一、简单操作 点击按钮&#xff08;鼠标左键&#xff09;&#xff1a;click()清空输入框&…...

3389,为了保障3389端口的安全,我们可以采取的措施

3389端口&#xff0c;作为远程桌面协议&#xff08;RDP&#xff09;的默认端口&#xff0c;广泛应用于Windows操作系统中&#xff0c;以实现远程管理和控制功能。然而&#xff0c;正因为其广泛使用&#xff0c;3389端口也成为许多潜在安全威胁的入口。因此&#xff0c;确保3389…...

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…...

最佳 Mac 数据恢复:恢复 Mac 上已删除的文件

尝试过许多 Mac 数据恢复工具&#xff0c;但发现没有一款能达到宣传的效果&#xff1f;我们重点介绍最好的 Mac 数据恢复软件 没有 Mac 用户愿意担心数据丢失&#xff0c;但您永远不知道什么时候会发生这种情况。无论是意外删除 Mac 上的重要文件、不小心弄湿了 Mac、感染病毒…...

芋道系统,springboot+vue3+mysql实现地址的存储与显示

1.效果图 2.前端实现&#xff1a; <el-form-item label"地址" prop"entrepriseAddress"><el-cascaderv-model"formData.entrepriseAddress"size"large":options"region"/></el-form-item> //导入组件 im…...

【C++】C++11新特性:列表初始化、声明、新容器、右值引用、万能引用和完美转发

目录 一、列表初始化 1.1 { } 初始化 1.2 std::initializer_list 二、声明 2.1 auto 2.2 decltype 2.3 nullptr 三、新容器 四、右值引用和移动语义 4.1 左值和左值引用 4.2 右值和右值引用 4.3 左值引用与右值引用比较 4.4 右值引用使用场景和意义&#xff1a;移…...

【IB Protocal Serial--WQE】

IB Protocal Serial--WQE 1 Intro1.1 What1.2 IBA WQE 本系列文章介绍RDMA技术的具体实现–InfiniBand Protocal&#xff1b; Introduce the features, capalities,components, and elements of IBA. the principles of operation. 1 Intro 1.1 What 理解IB协议下面这三句话对…...

C++ 混合运算的类型转换

一 混合运算和隐式转换 257 整型2 浮点5 行吗&#xff1f;成吗&#xff1f;中不中&#xff1f; C 中允许相关的数据类型进行混合运算。 相关类型。 尽管在程序中的数据类型不同&#xff0c;但逻辑上进行这种运算是合理的相关类型在混合运算时会自动进行类型转换&#xff0c;再…...

线性时间选择

给定线性序集中n个元素和一个整数k&#xff0c;1≤k≤n&#xff0c;要求找出这n个元素中第k小的元素 #include<iostream> #include<cstdlib> #include<time.h> using namespace std; int a[100]; int Random(int left,int right) {srand(time(NULL));return …...

【对算法期中卷子的解析和反思】

一、程序阅读并回答问题&#xff08;共30分&#xff09; #include<cstdio>#include<cstring>#include<iostream>using namespace std;char chess[10][10];int sign[10];int n, k, ans;void dfs(int x, int k) { if (k 0){ans;return; } if (xk-1 >…...

sudo apt update sudo: apt: command not found

CentOS或RHEL&#xff08;Red Hat Enterprise Linux&#xff09;系统上&#xff0c;包管理器是yum或dnf&#xff0c;而不是apt。您可以使用yum或dnf来安装软件包。以下是如何在CentOS或RHEL上安装Git的详细步骤&#xff1a; 1. 使用yum安装Git 首先&#xff0c;更新软件包列表&…...

ios:文本框默认的copy、past改成中文复制粘贴

问题 ios 开发&#xff0c;对于输入框的一些默认文案展示&#xff0c;如复制粘贴是英文的&#xff0c;那么如何改为中文的呢 解决 按照路径找到这个文件 ios/项目/Info.plist&#xff0c;增加 <key>CFBundleAllowMixedLocalizations</key> <true/> <…...

Qt moc系统的黑魔法?

Qt的元对象系统&#xff08;Meta-Object System&#xff09;是Qt框架的核心功能之一&#xff0c;为C语言增加了一些动态特性&#xff0c;借助元对象系统Qt可以实现以下功能 信号与槽机制&#xff08;Signals and Slots&#xff09;运行时类型信息&#xff08;Run-Time Type In…...

MyBatis开发中常用总结

文章目录 常用MyBatis参数映射单个参数多个参数使用索引【不推荐】Param注解Map传参POJO【推荐】List数组 动态标签\<if>标签\<trim>标签\<where>标签\<set>标签\<foreach>标签 MyBatis查询一对一一对多 常用MyBatis参数映射 单个参数 XML中可…...

Git基本使用教程(学习记录)

参考文章链接&#xff1a; Git教程&#xff08;超详细&#xff0c;一文秒懂&#xff09; RUNOOB Git教程 Git学习记录 1Git概述 1.1版本控制软件功能 版本管理&#xff1a;更新或回退到历史上任何版本&#xff0c;数据备份共享代码&#xff1a;团队间共享代码&#xff0c;…...

【Linux-RTC】

Linux-RTC ■ rtc_device 结构体■ RTC 时间查看与设置■ 1、时间 RTC 查看■ 2、设置 RTC 时间 ■ rtc_device 结构体 Linux 内核将 RTC 设备抽象为 rtc_device 结构体 rtc_device 结构体&#xff0c;此结构体定义在 include/linux/rtc.h 文件中 ■ RTC 时间查看与设置 ■ 1…...

机器学习目录

文章目录 基本概念有监督学习回归问题分类问题 无监督学习聚类问题异常检测 基本概念 pass 有监督学习 回归问题 通过拟合函数&#xff0c;解决连续值的预测问题梯度下降法优化&#xff1b;最小二乘法求解&#xff1b;度量指标 均方误差&#xff1b;均方根误差&#xff1b;平…...

React开发环境配置详细讲解-04

环境简介 前端随着规范化&#xff0c;可以说规范和环境插件配置满天飞&#xff0c;笔者最早接触的是jquery&#xff0c;那个开发非常简单&#xff0c;只要引入jquery就可以了&#xff0c;当时还写了一套UI框架&#xff0c;至今在做小型项目中还在使用&#xff0c;show一张效果…...

岗亭厂家直销:揭秘源头工厂如何帮你省下30%采购成本

在2026年1月的今天&#xff0c;户外岗亭作为城市管理、社区安防及商业服务的关键节点&#xff0c;其市场需求持续增长。然而&#xff0c;行业在快速发展的同时&#xff0c;也暴露出一些亟待解决的技术与成本挑战。从技术层面看&#xff0c;传统岗亭产品普遍面临结构稳定性不足、…...

棉花打包机的设计【说明书(论文)+CAD+solidworks】

棉花打包机作为农业机械化领域的关键设备&#xff0c;其核心作用在于将散状棉花高效压缩成标准化包型&#xff0c;以满足运输、仓储及后续加工的工艺需求。传统打包方式依赖人工或简单机械&#xff0c;存在效率低、包型不均、劳动强度大等问题&#xff0c;而现代棉花打包机通过…...

PdfiumAndroid完全指南:从集成到高级应用

PdfiumAndroid完全指南&#xff1a;从集成到高级应用 【免费下载链接】PdfiumAndroid 项目地址: https://gitcode.com/gh_mirrors/pd/PdfiumAndroid PdfiumAndroid是一款专为Android开发打造的PDF渲染库&#xff0c;基于Pdfium原生库提供API级别14及以上设备的PDF文件处…...

将嵌套循环中的Java对象数组转换为HashMap以优化性能

本文旨在指导开发人员如何通过将嵌套循环转换为Hashmap来优化Java代码的性能&#xff0c;特别是当涉及到对象属性的相等性检查时。通过使用Hashmap的快速搜索特性&#xff0c;可以显著降低时间复杂性&#xff0c;提高代码执行效率。本文将提供详细的步骤和示例代码&#xff0c;…...

【Zynq 进阶一】深度解析 PetaLinux 存储布局:NAND Flash 分区与 DDR 内存分配全攻略

【Zynq 进阶】深度解析 PetaLinux 存储布局&#xff1a;NAND Flash 分区与 DDR 内存分配全攻略 文章目录【Zynq 进阶】深度解析 PetaLinux 存储布局&#xff1a;NAND Flash 分区与 DDR 内存分配全攻略&#x1f4dd; 前言&#x1f4e6; 第一部分&#xff1a;大局观——NAND 与 D…...

【Python AI 工具实战宝典】:20个高复用AI用例+开箱即用代码模板,限时开源库清单泄露!

第一章&#xff1a;Python AI 工具生态全景与实战价值定位Python 已成为人工智能开发的事实标准语言&#xff0c;其核心优势不在于单一库的性能&#xff0c;而在于高度协同、分层清晰的工具生态体系。从底层计算&#xff08;NumPy、CuPy&#xff09;、模型构建&#xff08;PyTo…...

从Python转C++必看:C++20的starts_with/ends_with和Python有何不同?5个易错点详解

从Python转C必看&#xff1a;C20的starts_with/ends_with和Python有何不同&#xff1f;5个易错点详解 当你在Python中熟练使用startswith()和endswith()多年后&#xff0c;突然切换到C20的starts_with和ends_with&#xff0c;可能会觉得"这不就是换个语法吗&#xff1f;&q…...

高通平台USB充电背后的秘密:从SBL1阶段到Kernel的电池ID识别全解析

高通平台USB充电与电池ID识别的深度技术解析 在Android设备开发中&#xff0c;电源管理系统的稳定性直接影响用户体验。作为底层驱动工程师&#xff0c;理解高通平台从硬件到软件的完整充电流程至关重要。本文将深入剖析从XBL阶段到Kernel层的电池识别机制&#xff0c;揭示BATT…...

汽车电子工程师必看:如何用MPC5643L实现ASIL-D级别的功能安全设计(附完整代码示例)

汽车电子工程师必看&#xff1a;如何用MPC5643L实现ASIL-D级别的功能安全设计&#xff08;附完整代码示例&#xff09; 在智能驾驶技术快速发展的今天&#xff0c;功能安全已成为汽车电子系统设计的核心考量。作为汽车电子工程师&#xff0c;我们面临的挑战不仅在于实现复杂功…...

杰理之人声消除额外保留部分频率声音办法【篇】

将原始声音分为两份&#xff0c;一份走原先的人声消除&#xff0c;另一份走EQ调节 最后输出声音 原先人声消除效果&#xff08;左-右&#xff09; EQ调节后声音...