当前位置: 首页 > 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一张效果…...

终极指南:SwiftUI-experiments中的粒子动画实现技巧与实战教程

终极指南&#xff1a;SwiftUI-experiments中的粒子动画实现技巧与实战教程 【免费下载链接】SwiftUI-experiments Examples with SwiftUI and other Apple frameworks that showcase various interactions, animations and more 项目地址: https://gitcode.com/gh_mirrors/sw…...

AURIX Tricore TC397开发实战:基于UDE的仿真调试与问题排查指南

1. 环境准备与工具安装 第一次接触AURIX Tricore TC397的开发板时&#xff0c;我完全被它强大的多核架构吸引住了。这款芯片在汽车电子领域应用广泛&#xff0c;但调试过程确实让不少新手头疼。经过几个项目的实战&#xff0c;我总结出一套基于UDE的调试方法&#xff0c;能帮你…...

Doramagic开源工具箱:开发者效率提升的模块化实践

1. 项目概述&#xff1a;Doramagic&#xff0c;一个为开发者打造的魔法工具箱最近在GitHub上闲逛&#xff0c;发现了一个挺有意思的项目&#xff0c;叫“tangweigang-jpg/Doramagic”。光看这个名字&#xff0c;可能有点摸不着头脑&#xff0c;但点进去一看&#xff0c;发现这其…...

基于FET6254-C多核异构处理器的智能运动控制系统设计与实践

1. 项目概述&#xff1a;当运动控制遇上嵌入式智能最近在做一个智能运动控制的项目&#xff0c;从传统的PLC方案转向了更灵活、更智能的嵌入式平台。选型过程中&#xff0c;飞凌嵌入式的FET6254-C核心板进入了我的视野&#xff0c;经过一番深度评估和实际测试&#xff0c;它确实…...

MSP430铁电超值系列MCU:25美分实现25种外设的嵌入式设计实战

1. 项目概述&#xff1a;为什么是MSP430铁电超值系列&#xff1f;在嵌入式开发的广阔世界里&#xff0c;选型往往是项目成败的第一步。面对琳琅满目的微控制器&#xff08;MCU&#xff09;&#xff0c;工程师们常常在性能、成本、功耗和开发便利性之间反复权衡。今天我想和大家…...

5分钟学会无损视频修复:untrunc让损坏MP4/MOV文件瞬间复活

5分钟学会无损视频修复&#xff1a;untrunc让损坏MP4/MOV文件瞬间复活 【免费下载链接】untrunc Restore a truncated mp4/mov. Improved version of ponchio/untrunc 项目地址: https://gitcode.com/gh_mirrors/un/untrunc 你是否经历过重要视频突然无法播放的绝望时刻…...

Cursor配置管理:使用符号链接与CLI实现多项目环境一键切换

1. 项目概述&#xff1a;为什么我们需要管理Cursor的配置&#xff1f;如果你和我一样&#xff0c;每天大部分时间都泡在Cursor这个AI驱动的代码编辑器里&#xff0c;那你肯定遇到过这样的场景&#xff1a;早上打开电脑&#xff0c;准备开始一个全新的前端项目&#xff0c;你熟练…...

监控与日志:Prometheus+Grafana实时追踪GPU、显存、推理延迟与错误率

系列导读 你现在看到的是《本地大模型私有化部署与优化:从入门到生产级实战》的第 8/10 篇,当前这篇会重点解决:让你的本地大模型服务像云服务一样可观测,提前发现并解决性能问题。 上一篇回顾:第 7 篇《量化部署终极指南:从GPTQ到AWQ,精度损失与显存节省的平衡艺术》…...

宇视摄像机室外安装防腐说明

摄像机室外安装防腐说明一、开篇介绍防腐能力是户外摄像机长期稳定运行的关键。设备金属外壳一旦腐蚀&#xff0c;易引发起雾、进水、性能下降&#xff0c;严重时会导致整机损坏。宇视户外产品均按对应环境防护标准设计&#xff0c;可根据现场腐蚀等级选择适配产品。本文为工程…...

零代码物联网实战:用WipperSnapper与Adafruit IO快速采集模拟与I2C传感器数据

1. 项目概述与核心价值在嵌入式开发和物联网项目的起步阶段&#xff0c;很多开发者&#xff0c;尤其是刚接触硬件的朋友&#xff0c;常常会卡在两个看似基础却至关重要的环节上&#xff1a;如何让微控制器“感知”到物理世界的连续变化&#xff0c;以及如何高效、可靠地读取那些…...