堆排序(HeapSort)详解

news2025/1/12 16:03:12

堆排序

  • 一,思考
  • 二,算法步骤
    • 2.1向上调整建堆
    • 2.2关键思路
    • 2.3完整代码
    • 补充:向下调整建堆
  • 三,总结

一,思考

我们上一篇文章讲到了堆的基本实现,那么堆排序我们就先借助堆的结构来实现。

void HeapSort(HP* hp)
{
	int a[] = { 65,100,70,32,50,60 };
	HeapInit(&hp);
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		HeapPush(&hp, a[i]);
	}
	HeapPrint(&hp);
	while (!HeapEmpty(&hp))
	{
		printf("%d ", HeapTop(&hp));
		HeapPop(&hp);
	}
	HeapPrint(&hp);
	HeapDestroy(&hp);

}

我们先创建堆,然后依次取堆顶的数据,虽然这种打印出来是正确的顺序,但是本质上我们只是依次取了数据,数组a的数据根本没有变。所以我们要对这个代码做出一点改变。

void HeapSort(int*a,int n)
{
	HP hp;
	HeapInit(&hp);
	for (int i = 0; i < n; i++)
	{
		HeapPush(&hp, a[i]);
	}
	int i = 0;
	while (!HeapEmpty(&hp))
	{
		/*printf("%d ", HeapTop(&hp));*/
		a[i++] = HeapTop(&hp);
		HeapPop(&hp);
	}
	HeapPrint(&hp);
	HeapDestroy(&hp);

}

我们在这个代码中加入a[i++] = HeapTop(&hp);这个就依次把a数组中的数据依次取代。但是这个代码依旧有缺陷。
我们刚刚提到我们是有了堆结构,才写出这个堆排序的,所以这个很大程度上他很麻烦,要有堆结构才能有堆排。所以我们就要想有没有什么写法不需要对结构就可以写出这个排序。

二,算法步骤

我们在写堆的时候提到了两种调整,一个是向上调整,一个是向下调整我们接下来真正的堆排序就要从他们入手。
***注意
既然是堆排序,那么我们就要先建堆。说到建堆我们这个又有一个需要考虑的问题,我们如果要排升序,我们应该建大堆还是小堆呢?我们正常思路就是排升序就建小堆,因为这样根就是最小的数可以直接取出。但是我们要考虑完全,取完了最小的数那么接下来呢?把剩下的数再排,让下一个数当根,这样又出现了一个问题就是,兄弟关系变成了父子,那么堆就被破坏了。所以这种方法是不可行的。排升序应该建大堆。
堆排序:升序建大堆;降序建小堆
(我们接下来都是以排升序为例)

2.1向上调整建堆

在这里插入图片描述
我们先选择用向上调整去建堆,我们先把70设为跟,然后尾插,在向上调整数的位置,用一个循环就可达到,也是非常的简单。

	for (int i = 0; i < n; i++)
	{
		Adjustup(a,i);
	}

2.2关键思路

建完了堆我们就要开始排序了,
在这里插入图片描述

我们在堆的删除中用了,把根和最后一个位置交换,然后再向下调整。当然这里我们引用了这种方法,我们先交换根和最后一个数,这样最大的数我们就排好了,这里我们还设置了一个end,每牌好一个数,end就–去找次大的数。这样用循环控制,直到end<0我们的堆排就完成了。

2.3完整代码

void HeapSort(int* a, int n)
{
	//向上调整建堆
	for (int i = 0; i < n; i++)
	{
		Adjustup(a,i);
	}

	int end = n - 1;
	while (end>0)
	{
		Swap(&a[end], &a[0]);
		AdjustDown(a,end,0);
		end--;
	}
}

补充:向下调整建堆

上面的堆排已经没什么大问题了,但是他两种调整都用了,我们在写堆排的时候还是有些麻烦,所以有没有什么办法在简便一些呢?这里我们就用向下调整建堆
在这里插入图片描述
刚刚的向上调整建堆是从上到下,而向下调整则是从下到上,我们都知道向下调整的前提是:左右子树都是堆
那么我们就从这一点入手,我们找到第一个非叶子节点,叶子节点没有排的必要,所以我们从非叶子节点出发,他的左右孩子都是堆,然后我们就可以向下调整,用循环控制,当然这里我们要注意,非叶子节点的下标,最后一个值的下标是n-1,那么他的父亲(第一个非叶子节点)就是[(n-1)-1]/2,然后再–就找到了上一个节点。

void HeapSort(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[end], &a[0]);
		AdjustDown(a,end,0);
		end--;
	}
}

三,总结

堆排序需要多多的去画图理解,加深印象,堆的内容也是完成了,下一节我们要进入二叉树的链式结构了。

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

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

相关文章

2023年10月份最新香港优才计划申请攻略,附政策、申请流程、续签!

2023年10月份最新香港优才计划申请攻略&#xff0c;附政策、申请流程、续签&#xff01; 2023年10月份香港优才计划利好政策持续推进&#xff0c;越来越多的人咨询香港优才计划申请事宜。现在为大家整理了一份全面的优才申请攻略&#xff0c;如果你计划在今年申请香港优才&…

MySQL基础练习题

数据表介绍 --1.学生表 Student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Course(CId,Cname,TId) --CId 课程编号,Cname 课程名称,TId 教师编号 --3.教师表 Teacher(TId,Tname) --TId 教师编号,Tname 教师姓名 --4.成绩…

2021年06月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python编程&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 下列程序运行的结果是&#xff1f; s hello print(sworld)A: sworld B: helloworld C: hello D: world 答案&#xff1a…

数据飞轮拆解车企数据驱动三板斧:数据分析、市场画像、A/B 实验

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 近日&#xff0c;火山引擎数智平台&#xff08;VeDI&#xff09;2023 数据飞轮汽车行业研讨会在上海举办&#xff0c;活动聚焦汽车行业数字化转型痛点&#xff0c;从…

NEWCC:新时代的区块链生态新币私募造势平台

在当今区块链领域&#xff0c;这项技术已经为金融资产注入了全新的生机&#xff0c;同时也为初创企业提供了新的商业模式和融资机会。通过代币的金融属性&#xff0c;企业和项目方得以实现资本的初期积累&#xff0c;同时在区块链空间以更低成本和更高效率进行交易和服务创新。…

适合在虚拟化环境中部署 Kubernetes 的三个场景

在《虚拟化 vs. 裸金属&#xff1a;K8s 部署环境架构与特性对比》文章中&#xff0c;我们从架构和特性的角度&#xff0c;对比了在虚拟化和裸金属环境部署 Kubernetes 的优劣势&#xff0c;并在文末列举了两者更适合的应用场景。本文&#xff0c;我们将聚焦以虚拟化环境支持 K8…

英语——分享篇——每日200词——3401-3581

3401——colony——[kɒlənɪ]——n.殖民地&#xff0c;(某一类人的)聚居区——colony——co可乐(熟词coke)lon笼(拼音)y树杈(编码)——把可乐装在笼子里用树杈挑着去殖民地——The newly-occupied Italian colony of Libya rose in revolt in 1914.——意大利新占领的殖民地利…

低成本IC上岸攻略—IC设计网课白嫖篇

数字电路基础 清华大学 王红主讲&#xff1a;数字电子技术基础 西安电子科技大学 任爱锋主讲&#xff1a;数字电路与逻辑设计 模拟电路基础 上交大 郑益慧主讲&#xff1a;模拟电子技术基础 清华大学 华成英主讲&#xff1a;模拟电子技术基础 半导体物理&#xff1a; 西…

图(graph)的遍历-----广度优先遍历(BFS)

目录 前言 广度优先遍历&#xff08;BFS&#xff09; 1.基本概念 2.算法过程 图的广度优先遍历 1.邻接矩阵 2.邻接表 3.算法比较 前言 上一期学习了图的深度优先遍历&#xff0c;&#xff08;深度优先遍历&#xff1a;图(graph)的遍历----深度优先(DFS)遍历-CSDN博客…

玄铁C906——物理内存保护(PMP)介绍

1、前言 &#xff08;1&#xff09;本文描述的是玄铁C906的物理内存保护机制的实现中&#xff0c;与RISC-V架构手册中完整PMP机制的差异部分&#xff1b; &#xff08;2&#xff09;RISC-V架构的PMP机制&#xff0c;参考博客&#xff1a;《RISC-V架构——物理内存属性和物理内存…

C算法:输入一个数n,输出1到n之间所有的质数

需求&#xff1a; 写一个函数&#xff0c;输入一个数n&#xff0c;输出1到n之间所有的质数。&#xff08;注&#xff1a;质数又称素数。一个大于1的自然数&#xff0c;除了1和它自身外&#xff0c;不能被其他自然数整除的数叫做质数。&#xff09; 输入样例&#xff1a; 10 …

Pytorch--3.使用CNN和LSTM对数据进行预测

这个系列前面的文章我们学会了使用全连接层来做简单的回归任务&#xff0c;但是在现实情况里&#xff0c;我们不仅需要做回归&#xff0c;可能还需要做预测工作。同时&#xff0c;我们的数据可能在时空上有着联系&#xff0c;但是简单的全连接层并不能满足我们的需求&#xff0…

《数字图像处理-OpenCV/Python》连载(26)绘制椭圆和椭圆弧

《数字图像处理-OpenCV/Python》连载&#xff08;26&#xff09;绘制椭圆和椭圆弧 本书京东优惠购书链接&#xff1a;https://item.jd.com/14098452.html 本书CSDN独家连载专栏&#xff1a;https://blog.csdn.net/youcans/category_12418787.html 第 4 章 绘图与鼠标交互 本章…

在keil中debug分析单片机数据和函数调用过程(c51为例),使用寄存器组导致错误原因分析

寄存器参考 参考2 [寄存器组使用using参考]&#xff08;https://blog.csdn.net/weixin_46720928/article/details/110221835&#xff09; keil中的using关键字参考 官方文档里关于using的说明可参阅2个地方&#xff0c;&#xff08;1&#xff09;keil软件菜单栏->Help->…

被邀请为期刊审稿时,如何做一个合格的审稿人?官方版本教程来喽

审稿是学术研究中非常重要的环节&#xff0c;它可以确保研究的科学性和严谨性。审稿人的任务是检查文章是否符合学术规范&#xff0c;是否具有创新性&#xff0c;是否具有科学价值&#xff0c;以及是否符合期刊的定位和风格。因此&#xff0c;审稿人需要具有扎实的学术背景和丰…

SHELL编程基础2

文章目录 if语句if单分支应用案例 if多分支案例 for循环while循环正则表达式基本正则Perl兼容的正则 if语句 if单分支 if单分支的语法组成&#xff1a; 方式一: if 条件测试;then 命令序列 fi方式二 if 条件测试then 命令序列 fi应用案例 [rootsom day01]# vim user_v2.…

WPF中的绑定知识详解(含案例源码分享)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

带你深入了解git

目录 1、Git介绍1.1git是什么工具1.2git起到的作用1.2.1 个人开发&#xff1a;1.2.2 多人开发&#xff1a; 2、Git安装与下载项目代码2.1 下载安装git2.2 从仓库下载代码 3、创建仓库及提交代码3.1 创建仓库3.2 将本地代码以及文件提交到远程仓库3.2.1git全局配置3.2.2 远程仓库…

领域驱动设计:基于DDD的微服务设计实例

文章目录 项目基本信息战略设计战术设计后续的工作 用一个项目来了解 DDD 的战略设计和战术设计&#xff0c;走一遍从领域建模到微服务设计的全过程&#xff0c;一起掌握 DDD 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…

【数据中台建设系列之二】数据中台-数据采集

​ 【数据中台建设系列之二】数据中台-数据采集 上篇文章介绍了数据中台的元数据管理&#xff0c;相信大家对元数据模块的设计和开发有了一定的了解&#xff0c;本编文章将介绍数据中台另一个重要的模块—数据采集。 一、什么是数据采集 数据采集简单来说就是从各种数据源中抓…