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

news2024/12/23 12:14:05

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.coloradmin.cn/o/1700699.html

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

相关文章

linux centos nginx配置浏览器访问后端(tomcat日志)

1、配置nginx访问tomcat日志路径 vim /usr/local/nginx/conf/nginx,conflocation ^~ /logs {autoindex on;autoindex_exact_size on;autoindex_localtime on;alias /home/tomcat/apache-tomcat-9.0.89-1/logs;}###配置讲解### 1、location ^~ /logs { … }: location&#xf…

抖音IP地址频繁变动:背后的原因与解读

在抖音这个短视频平台的日常使用中&#xff0c;不少用户可能注意到了自己的IP地址有时会频繁变动。这种现象不仅引起了用户的好奇&#xff0c;也引发了关于个人隐私、账号安全以及平台政策的一系列讨论。那么&#xff0c;抖音IP地址换来换去什么意思&#xff1f;这背后又隐藏着…

最新ETF市场全景画像

根据天软指数基金因子库&#xff0c;分析宽基、行业和主题ETF表现&#xff0c;目前已全部上线公众号&#xff0c;更多内容可关注天软公众号&#xff01;

2024年上半年系统架构设计师——案例第二题——UML相关

这个只记到一个大概了 主题干&#xff0c;说明人员访客系统 题目1 9分 问序列图信息类型和特点 题目2 序列图填空 好像是10分吧 访客系统的序列图 题目3 6分 说明软件分析和设计时的和UML图有关原则&#xff1f;

RocketMq源码解析四:生产者Producer启动

一、主要接口和类 生产者服务核心接口和类的关系如下图所示&#xff1a; MQProducer是生产者解耦&#xff0c;这里找几个有代表性的方法 // 同步发送消息 SendResult send(final Message msg) throws MQClientException, RemotingException, MQBrokerException,InterruptedExce…

如何使用Cloudways搭建WordPress网站

如今&#xff0c;搭建网站已经变得非常简单&#xff0c;这主要得益于开源的CMS建站系统的兴起。即使是不懂编程的人也能轻松搭建自己的网站&#xff0c;这些CMS系统提供了丰富的主题模板和插件&#xff0c;使用户可以通过简单的拖放和配置操作来建立自己的网站。 WordPress是目…

mysql中单表查询的成本

大家好。我们知道MySQL在执行一个查询时&#xff0c;经常会有多个执行方案&#xff0c;然后从中选取成本最低或者说代价最低的方案去真正的执行查询。今天我们来聊一聊单表查询的成本。 那么到底什么是成本呢&#xff1f;这里我们说的成本或者代价是由两方面组成的&#xff1a…

全新交友盲盒+付费进群二合一源码 包含全套源码+教程

盲盒交友脱单系统源码&#xff0c;带教程&#xff0c;免授权这套源码已经替你们搭建测试过了 附带进群系统&#xff0c;定位是正常的 申明需要无限回调&#xff0c;没有回调的搭建出来不能用不要说源码不能用 全新系统方便大家使用&#xff0c;已经录制好详细的教程&#xf…

解决问题的多样手段:不止律师

在我们日常生活和工作中&#xff0c;总是会遇到各种各样的问题。有时我们会不由自主地想到找律师打官司&#xff0c;认为这是解决问题的唯一途径。然而&#xff0c;解决问题其实有很多手段&#xff0c;律师和法庭只是其中的一种。事实上&#xff0c;只要能够发现问题并及时解决…

大模型应用:LLM基本原理及应用场景

1.背景 23年以来&#xff0c;随着OpenAI公司的ChatGPT横空出世&#xff0c;大模型一词开始火爆全球。国内外以OpenAI、Google、百度、阿里、字节等大厂为代表&#xff0c;相继推出一系列大模型及其应用&#xff0c;涉及社交、问答、代码助手等多个方面。 目前主流的大模型及产…

从零构建vue3+ts+vite项目打包及项目依赖配置

❗️❗️❗️❗️ 写在最前: 本文是根据B站作者 月光分层 视频vuets 工程化配置以及作者笔记稍作整理 &#x1f496;&#x1f496;作者B站地址https://space.bilibili.com/14110850 &#x1f496;&#x1f496;视频教程地址vuets 工程化配置 &#x1f496;&#x1f496;作者微信…

自反馈 Transformer:一种针对真实世界胰腺神经内分泌肿瘤数据的多标签诊断模型

文章目录 Self-feedback Transformer: A Multi-label Diagnostic Model for Real-World Pancreatic Neuroendocrine Neoplasms Data摘要方法实验结果 Self-feedback Transformer: A Multi-label Diagnostic Model for Real-World Pancreatic Neuroendocrine Neoplasms Data 摘…

最早做“转化医学”的国货护肤品牌,发力了!

文章来自化妆品行业媒体青眼 作者小朱 放眼全球护肤市场&#xff0c;皮肤科学的力量正在前所未有地凸显&#xff0c;多个国际美妆巨头专门设立了皮肤科学部门&#xff0c;国内皮肤科医生参与护肤品牌创建也成为一股风潮。 据青眼不完全统计&#xff0c;近年来&#xff0c;至少…

使用阿里云服务器部署(完整步骤)

部署项目前需要环境&#xff1a;阿里云云服务器ECS&#xff0c;宝塔面板 阿里云云服务器ECS实例创建过程 先登录阿里云网站注册账号,进入控制台左侧导航栏中云服务器ECS页面根据自己的需求去创建一个新的实例&#xff08;需要付费&#xff09;如果是学生的话&#xff0c;完成…

粤嵌—2024/5/13—删除排序链表中的重复元素(✔)

代码实现&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* deleteDuplicates(struct ListNode *head) {if (head NULL || head->next NULL) {return head;}struct ListNode *…

FFmpeg开发笔记(三十一)使用RTMP Streamer开启APP直播推流

RTMP Streamer是一个安卓手机端的开源RTMP直播推流框架&#xff0c;可用于RTMP直播和RTSP直播&#xff0c;其升级版还支持SRT直播&#xff08;腾讯视频云就采用SRT协议&#xff09;。RTMP Streamer支持的视频编码包括H264、H265、AV1等等&#xff0c;支持的音频编码包括AAC、G7…

fastadmin二次开发 修改默认的前端弹出样式

需要修改fastadmin后台默认的弹出提示样式效果&#xff1a; 在项目里搜索这个关键词&#xff1a;Toastr 首先这个文件&#xff0c;里面的success和error就是弹出提示的方法。 public/assets/js/fast.js 然后是下面这个文件&#xff1a; public/assets/js/require-form.js 你…

ROS2入门21讲__第20讲__RQT:模块化可视化工具

目录 前言 rqt介绍 日志显示 图像显示 发布话题数据/调用服务请求 绘制数据曲线 数据包管理 节点可视化 前言 ROS中的Rviz功能已经很强大了&#xff0c;不过有些场景下&#xff0c;我们可能更需要一些简单的模块化的可视化工具&#xff0c;比如只显示一个摄像头的图像…

【北京市政府网_注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

CDC 数据实时同步入湖的技术、架构和方案(截至2024年5月的现状调研)

近期&#xff0c;对 “实时摄取 CDC 数据同步到数据湖” 这一技术主题作了一系列深入的研究和验证&#xff0c;目前这部分工作已经告一段落&#xff0c;本文把截止目前&#xff08;2024年5月&#xff09;的研究结果和重要结论做一下梳理和汇总。为了能给出针对性的技术方案&…