堆排序

在上一篇博客中讲解了堆,现在来讲讲基于堆实现的排序,即堆排序。

要用堆排序,首先我们需要先建堆,建堆有两种方法:向上调整法建堆和向下调整法建堆。接下来我们分析这两种方法的时间复杂度。

向上调整法:

向下调整法: 

根据上面的分析,我们得到:向下调整法建堆更高效,所以接下来的堆排序实现过程中我们用向下调整法建堆。向下调整法建堆需要从第一个非叶子结点开始,然后调整完后调整上边的(即从下往上),如果从下标为0的结点开始向下调整会有问题,因为我们调整时是交换孩子和父亲,而当其深度大于2时,并且在后边(隔了几层)有更小的数时,交换后是无法保证最小的数在堆顶的,因为这时候是按照从上往下的顺序进行向下调整,在下边的更小的数是不能再往上交换的(除了其父父亲)。

接下来我们分析实现堆排序的过程。

排序有升序和降序,而堆中有大堆和小堆,我们应该建大堆还是小堆呢?答案是升序建大堆,降序建小堆。

我们知道,大堆中堆顶元素是所有元素中最大的那个,小堆中堆顶元素是所有元素中最小的那个,堆排序便是依次来实现的。以降序为例,给定一个有n个元素的数组,当我们建好堆后,我们不断把堆顶元素与最后一个元素交换,这样最后一个元素就放好了,然后重新调整为小堆,在下一次交换时,针对的就是前n-1个数据了,然后一直这样交换下去,这便是堆排序的思想。

接下来上代码: 

//交换数据
void swap(HPDataType* x, HPDataType* y)
{HPDataType t = 0;t = *x;*x = *y;*y = t;
}//向下调整
void AdjustDown(HPDataType* a, int size, int parents)
{int child = parents * 2 + 1;//左孩子while (child < size){//如果右孩子更小,交换//注意child+1<size这个条件,实际最多只能访问到size-1的数据if (child + 1 < size && a[child] > a[child + 1]){child++;}if (a[child] < a[parents]){swap(&a[child], &a[parents]);parents = child;child = parents * 2 + 1;}else{break;}}
}//堆排序
void HeapSort(HPDataType* a, int n)
{//数组建堆(向下调整)int i = 0;//(n-1-1)/2是第一个非叶子结点for (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--;//注意调整和自减顺序,end是最后一个数的下标,交换完后,前边的数的个数即end}
}int main()
{int arr[10] = { 1,8,6,4,2,7,3,5,9,0 };HeapSort(arr, 10);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

 测试结果:

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xss.haozi.me靶场“0x0B-0x12”通关教程

君衍. 一、0x0B 实体编码绕过二、0x0C script绕过三、0x0D 注释绕过四、0X0E ſ符号绕过五、0x0F 编码解码六、0x10 直接执行七、0x11 闭合绕过八、0x12 闭合绕过 XSS-Labs靶场“1-5”关通关教程 XSS-Labs靶场“6-10”关通关教程 Appcms存储型XSS漏洞复现 XSS-Labs靶场“11-13、…

Java8中Stream流API最佳实践Lambda表达式使用示例

文章目录 一、创建流二、中间操作和收集操作筛选 filter去重distinct截取跳过映射合并多个流是否匹配任一元素&#xff1a;anyMatch是否匹配所有元素&#xff1a;allMatch是否未匹配所有元素&#xff1a;noneMatch获取任一元素findAny获取第一个元素findFirst归约数值流的使用中…

【C#】int+null=null

C#语法&#xff0c;这玩意不报错 intnullnull&#xff0c;有点不合逻辑 (Int32)(bizRepair0rder.CreateTime. Value - regues.Mlodifylime.Value).TotalMinutes (Int32)(bizRepair0rder.CreateTime. Value - reques.llodifylime.Value).TotalMinutes nullstring是引用类型&…

基于SpringBoot框架实现的B2B平台的医疗病历交互系统

采用技术 基于SpringBoot框架实现的B2B平台的医疗病历交互系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 管理员角色 医院管理 医院注册 医院文…

基于web的精品课程网站设计

基于web的精品课程网站设计 C#asp.netSqlServer 带论文 功能模块&#xff1a; 基于web的精品课程网站设计 C#asp.netSqlServer 学生功能模块 学生登录系统后&#xff0c;可以在留言板页面给老师进行留言&#xff0c;并且可以查看课程和题库 可以在首页进行考试并且可以修改…

基于Spring Boot+Vue的校园二手交易平台

目录 一、 绪论1.1 开发背景1.2 系统开发平台1.3 系统开发环境 二、需求分析2.1 问题分析2.2 系统可行性分析2.2.1 技术可行性2.2.2 操作可行性 2.3 系统需求分析2.3.1 学生功能需求2.3.2 管理员功能需求2.3.3游客功能需求 三、系统设计3.1 功能结构图3.2 E-R模型3.3 数据库设计…

【DL经典回顾】激活函数大汇总(十七)(Softmax2d附代码和详细公式)

激活函数大汇总&#xff08;十七&#xff09;&#xff08;Softmax2d附代码和详细公式&#xff09; 更多激活函数见激活函数大汇总列表 一、引言 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里&#xff0c;激活函数扮演着不可或缺的角…

双指针算法_复写零

题目&#xff1a; 给一个固定长度的数组arr&#xff0c;将数组中出现的每一个0都复写一遍&#xff0c;并且将其余元素都往右移动 且不要再超过数组长度的位置写入元素&#xff0c;在数组上直接修改 示例&#xff1a; 双数组模拟操作&#xff1a; 从示例来看&#xff0c;因为…

精简版 Obsidian 图床配置 PicGo+ gitee

精简版 Obsidian 图床配置 PicGo gitee 图床的作用 图床&#xff08;Image Hosting Service&#xff09;是一种在线服务&#xff0c;用于存储和托管用户上传的图片文件。用户可以将图片上传到图床服务器&#xff0c;并获得一个可访问的图片链接&#xff0c;然后可以在网页、博…

词令微信小程序怎么添加到我的小程序?

微信小程序怎么添加到我的小程序&#xff1f; 1、找到并打开要添加的小程序&#xff1b; 2、打开小程序后&#xff0c;点击右上角的「…」 3、点击后底部弹窗更多选项&#xff0c;请找到并点击「添加到我的小程序」&#xff1b; 4、添加成功后&#xff0c;就可以在首页下拉我的…

Linux使用Docker部署Registry结合内网穿透实现公网远程拉取推送镜像

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

day05-SpringBootWeb请求响应

请求响应&#xff1a; 请求&#xff08;HttpServletRequest&#xff09;&#xff1a;获取请求数据响应&#xff08;HttpServletResponse&#xff09;&#xff1a;设置响应数据 BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xf…