一篇文章讲透排序算法之堆排序

1.前言 

在学习这篇文章之前,请大家先学习堆这一数据结构中堆的概念,向下调整算法,向下调整建堆

有关堆的实现方式请参考:堆的实现

堆排序就是利用堆里面学习过的知识点进行排序,如何进行排序呢?

2.堆排序原理剖析

现在我们要对一个无序的数组升序排列,那么我们应该利用大堆还是小堆进行排序呢?

这时我们大家就会想,既然是升序排列,那么我们建一个小堆不就可以了吗,刚好小堆的第一个元素是最小的元素。

  • 建小堆可行性分析

好,那么我们现在来思考一下这种方法的可行性。

现在我们给出如下一个小堆。

现在我们可以确保根节点是最小的了,下面我就就要从第二层选最小的数了,这里我们选到了右子树2,但是根结点的左右两棵子树之间是没有联系的,我们应该如何判决左子树8和右子树2的子树们的关系呢?这时就需要我们遍历才能确定大小关系了,而后续的每一次比较都需要这么一个过程。时间复杂度就变的相当高了。若如此建堆,堆排序就是一个理解起来困难而时间复杂度又高的离谱的排序方法了

  • 建大堆可行性分析

既然建小堆不可以,那么,建大堆应该如何排序呢?又有没有优势呢?

首先,我们可以确定的一点是,大堆的堆顶一定是一整个堆中最大的元素。

但是我们排的是升序,最大的一个应该在堆的最后面才对,那么我们直接交换堆顶元素和堆尾元素的位置不就可以让堆的最后一个元素是最大的了嘛

这时,新的问题是,我们的交换破坏了堆原来的结构,那么这时我们需要做的工作则是恢复堆原来的结构。这不就是我们的向下调整算法所能做的事嘛,因此我们每次交换了之后用一个向下调整算法即可。

3.堆排序代码详细阐述

我们首先完成第一次交换和向下调整:

int end=n-1;//n是数组长度
swap(&arr[0], &arr[end]);
AdjustDown(a, end, 0);

下面我们要做的事情即将数组内所有的元素都按照这种方式进行排序,这就需要我们将上述代码嵌套进一个循环内,而由于此时最后一个元素已经是最大的了,因此我们需要剔除掉这个元素,在这里我们直接让end-1即可。

while (end>0)
{swap(&arr[0], &arr[end]);AdjustDown(a, end, 0);end--;
}

上述代码即可完成一次堆排序。

而由于我们传进来的数组的元素是无序的,因此我们首先需要将其调整为堆,之后再进行上述操作即可完成堆排序。

void AdjustDown(HPDataType * a, int n, int parent)
{// 先假设左孩子大int child = parent * 2 + 1;while (child < n)// 当child>=n时就说明child已经到达叶子节点了{// 先找出左右孩子节点中大的那个if (child + 1 < n && a[child + 1] > a[child])// 说明假设错误,交换小的那个子节点{child++;}// 和父亲节点进行比较if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
void HeapSort(int* a, int n)
{// 降序,建小堆// 升序,建大堆for (int parent = (n - 1 - 1) / 2; parent > 0; parent--){AdjustDown(a, n, parent);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

4.堆排序时间复杂度分析

初始化堆的时间复杂度为O(n)
n-1次删除操作的时间复杂度为O(nlogn)
所以总操作时间复杂度为O(nlogn)

由于每删除一个元素,总元素减一。
共有n-1次删除操作,操作时间应该为log(n)+log(n-1)+…+log(3)+log(2) = log(n!)。
又由于(n/2)^(n/2) ≤ n!≤ n ^ n,即 1/4*nlog(n) ≤ n! ≤ nlogn。常数可舍去,时间复杂度为O(nlogn)

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

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

相关文章

这方法真牛B!论文降重从81%直降1.9%

目录 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时二、获取途径三、论文从81&#xff05;降到1.9&#xff05;四、内容是别人的&#xff0c;话是自己的五、AI工具 --> 中文论文降重六、论文降重小技巧 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时 通过O…

Python-3.12.0文档解读-内置函数map()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 map(function, iterable, *iterables) 参数 返回值 示例 注意事项 参考…

如何让大模型更聪明?提升AI智能的关键策略

如何让大模型更聪明&#xff1f;提升AI智能的关键策略 &#x1f916; 如何让大模型更聪明&#xff1f;提升AI智能的关键策略摘要引言方向一&#xff1a;算法创新&#x1f680;1.1 自监督学习的崛起1.2 强化学习的应用 方向二&#xff1a;数据质量与多样性&#x1f4ca;2.1 数据…

乡村振兴的乡村公共服务提升:提升乡村公共服务水平,满足农民多样化需求,构建幸福美好的美丽乡村

目录 一、引言 二、乡村公共服务提升的必要性 &#xff08;一&#xff09;满足农民多样化需求 &#xff08;二&#xff09;促进乡村经济发展 &#xff08;三&#xff09;构建幸福美好的美丽乡村 三、乡村公共服务面临的挑战 &#xff08;一&#xff09;基础设施薄弱 &a…

粘土滤镜特效怎么弄?5个简易制作粘土软件一学就会

#是谁把夏天的氛围感拿捏了#&#xff0c;哦~原来是AI粘土特效。 这玩意儿最近在社交媒体上可是火得一塌糊涂&#xff0c;大家都在用它给自己的照片来个大变身&#xff0c;变成那种丑萌丑萌的粘土小人儿。 如果大家也想尝试一下&#xff0c;那就跟着我来看看几款超好用的粘土滤…

基于Django框架的项目搭建后台首页

(1). 创建数据库 osdb 进入MySQL数据库中&#xff0c;创建一个数据库名为&#xff1a;osdb 通过数据表结构来创建数据表&#xff1a; -- 员工信息表 CREATE TABLE user (id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 员工账号id,username varchar(50) DEFAULT NULL C…

MySQL:图文超详细教程MySQL5.7下载与安装

一、前言 MySQL 5.7 是一个重要的数据库管理系统版本&#xff0c;它带来了多项改进和新特性&#xff0c;本文将超详细的带大家手动安装一下MySQL5.7。 二、下载MySQL5.7版本 MySQL5.7安装包 链接&#xff1a;https://pan.baidu.com/s/1lz5rp9PwfyeHzkEfI_lW6A 提取码&#…

图卷积神经网络的简史 及其与卷积神经网络的异同

图卷积神经网络&#xff08;GCN&#xff09;已经在处理图结构数据方面取得了巨大的成功。在本小节中&#xff0c;我们将深入探讨图卷积神经网络的起源、发展历程&#xff0c;并提供一个简单的Python代码实现示例&#xff0c;以帮助读者更好地理解这一概念。 图卷积神经网络的简…

c# 贪心算法(Greedy Algo)

贪婪是一种算法范式&#xff0c;它逐步构建解决方案&#xff0c;始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 如果问题具有以下属性&#xff0c;则可以使用贪心法解决优化问题&#xff1a; 每一步&#xff0c;我们都可以做出当前看来最好的选择&…

IDEA 2024.1安装与破解

一、下载 官网地址&#xff1a;https://www.jetbrains.com/idea/download/other.html 二、安装 傻瓜式安装即可 三、破解 3.1 破解程序 网站&#xff1a;https://3.jetbra.in/ 3.2 获取激活码 点击*号部分即可复制成功

Vue——开发前的准备和创建一个vue的工程

文章目录 前言安装 Node js1、下载node.js2、安装node.js3、查看是否安装成功 创建 vue 工程Visual Studio Code 配置目录结构 前言 本篇博客主要讲解Vue开发前的环境配置与一些说明。 安装 Node js 环境需要安装配置一个nodejs 的环境。 vue3 最低nodejs 版本要求为 15.0 1…

[图解]产品经理创新模式01物流变成信息流

1 00:00:01,570 --> 00:00:04,120 有了现状的业务序列图 2 00:00:04,960 --> 00:00:08,490 我们就来改进我们的业务序列图了 3 00:00:08,580 --> 00:00:11,010 把我们要做的系统放进去&#xff0c;改进它 4 00:00:13,470 --> 00:00:15,260 怎么改进&#xff1f;…

揭秘OS模块:文件与文件夹的遍历艺术

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、os.listdir()&#xff1a;当前目录的扫描者 三、os.walk()&#xff1a;文件系…

揭秘!EasyRecovery如何轻松救回你的误删文件?

在数字化的今天&#xff0c;数据就像我们生活和工作的血液&#xff0c;流淌在每一个角落。无论是珍贵的家庭照片&#xff0c;还是关键的工作文件&#xff0c;都离不开数据的支撑。然而&#xff0c;数据丢失的情况时有发生&#xff0c;这可能是由于一次误删&#xff0c;一个系统…

PCL 二维凸包切片法计算树冠体积

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 二维凸包法是先将树冠等间隔分层切片,如图(e)采用二维凸包算法对每层…

FullCalendar日历组件集成实战(7)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

Pip,whl,源码编译安装Python库

pip安装 pip 是 Python 包管理工具&#xff0c;用于安装和管理 Python 包。pip 是 Python 开发中不可或缺的工具&#xff0c;能够帮助开发者轻松地管理项目所需的各种库和依赖。无论是安装新包、升级现有包还是卸载不需要的包&#xff0c;pip 都提供了简单而强大的命令来完成这…

中国改革报是什么级别的报刊?在哪些领域具有较高的影响力?

中国改革报是什么级别的报刊&#xff1f;在哪些领域具有较高的影响力&#xff1f; 《中国改革报》是国家发展和改革委员会主管的全国性综合类报纸。它在经济领域和改革发展方面具有重要的影响力&#xff0c;是传递国家政策、反映改革动态的重要平台。该报对于推动中国的经济改…

Pulsar 社区周报 | No.2024-05-24

“ 各位热爱 Pulsar 的小伙伴们&#xff0c;Pulsar 社区周报更新啦&#xff01;这里将记录 Pulsar 社区每周的重要更新&#xff0c;每周发布。 ” Pulsar Weekly Merge Stars 感谢以下的小伙伴&#xff0c;感谢你们本周为 Apache Pulsar 做的精彩贡献&#xff08;排名不分先后&…