【数据结构】堆排序 (超详细)

news2024/11/17 23:41:16

前言:
     前几次讲了如何构建一个堆以及TopK算法,那么这次给大家分享一下堆排序的两种方法。

在这里插入图片描述


方法一

直接暴力解决,建一个小堆,把数组的数据依次push,随后每次Pop堆顶,放进数组里。不过该方法因为建堆有消耗,所以空间复杂度为 O(N)。

步骤:
1.构建小堆
2.把数组里的数据依次Push(添加)进堆里面
3.取堆顶元素,放入数组,随后Pop掉堆顶

构建的小堆
在这里插入图片描述

随后取堆顶元素,放入数组,在Pop掉堆顶元素。
在这里插入图片描述

代码


//堆排序 方式一
void Heap_Sort1(int* data,int n)
{
	//建小堆
	HP hp;
	HeapInit(&hp);

	int i = 0;
	for (i = 0; i < n; i++)
	{
		//依次push
		HeapPush(&hp,data[i]);
	}

	int* tmp = data;
	//取每次堆顶元素
	while (!HeapEmpty(&hp))
	{
		//取堆顶
		HeapDataType top = HeapTop(&hp);
		//放入数组
		*tmp = top;
		tmp++;
		//移除堆顶
		HeapPop(&hp);
	}
}

排序结果
在这里插入图片描述


方法二

当然,我们都知道,建堆是有消耗的。如果我们排序还要建一个堆的话,那么空间复杂度就变成了O(N)。那么接下来就给大家分享一个时间复杂度O(1)的方法。那就是把数组直接变成堆。

在这里插入图片描述
还是这个数组,那么怎么把它构建成堆呢?我们先把它以完全二叉树的形式展现出来。
在这里插入图片描述

我们可以从倒数第二层开始,随后把它们都看成是一颗子树,依次向下调整。
在这里插入图片描述
我们先让 50开始向下调整,50比10要大,所以向下调整后,50和10会交换位置。然后60开始向下取整,因为70比40大,所以 60和40对比,60大于40,所以60和40交换位置。最后再往上一层开始继续向下调整。
在这里插入图片描述

那么如何找到最后一个父亲呢? 很简单,我们用 (最后一个孩子的小标 - 1 )/2就可以找到最后一个父亲。
所以我们要把数组构建成堆,那就从 (n-1-1) / 2 下标的位置开始依次往前进行向下调整,n为数组的长度。

代码

void Heap_Sort2(int* data, int n)
{
	assert(data);
	//把数组构建成堆
	int TailFather = (n - 1 - 1) / 2; //最后一个父亲
	while (TailFather >= 0)
	{
		//向下调整
		AdjustDown(data,n,TailFather);
		TailFather--;
	}

}

构建成小堆后,我们打印一下。
在这里插入图片描述
发现和我们图上的顺序是一样的
在这里插入图片描述
但是此刻,我们发现这不是有序的,那么我们还要继续调整。

此时我们发现,我们只能找到最小的,但是要找次小的,就非常麻烦。那怎么办呢? 我们排升序的话,可以试试建大堆!那我们来建大堆试试。

改一下向下调整的参数
在这里插入图片描述
此时数组变成了大堆
在这里插入图片描述
这时候就简单了,我们可以把70和10交换位置,随后把 10 - 40这段距离看成一个堆。

在这里插入图片描述

步骤:
1.把数组构建成堆,升序用大堆,降序用小堆。
2.让堆顶元素和最后一个元素进行交换。(不是数组的最后一个元素,而是堆的最后一个元素。)
3.交换完后,让堆顶元素向下取整。

代码

void Heap_Sort2(int* data, int n)
{
	assert(data);
	//把数组构建成堆
	int TailFather = (n - 1 - 1) / 2; //最后一个父亲
	while (TailFather >= 0)
	{
		//向下调整
		AdjustDown(data,n,TailFather);
		TailFather--;
	}

	for (int i = 0; i < n; i++)
		printf("%d ", data[i]);
	printf("\n");

	//最后一个元素
	int end = n - 1;
	while (end >= 0)
	{
		//交换位置
		Swap(&data[0], &data[end]);
		//向下取整
		AdjustDown(data, end, 0);
		end--;
	}

}

排序结果
在这里插入图片描述
如果我们想排降序呢?很简单,我们建小堆就行了。
只需要向下调整时,我们改成建小堆即可。

在这里插入图片描述

这样我们的降序就排好了
在这里插入图片描述


今天的堆排序就到了。
如果不知道堆怎么实现,可以看看我写的这篇文章【数据结构】堆的实现,以及用堆实现的TopK算法TopK问题。
完整代码已上传至git,git链接

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

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

相关文章

字体图标、平面转换、渐变

1、字体图标 字体图标 字体图标展示的是图标&#xff0c;本质是字体。处理简单的、颜色单一的图片 1.1、字体图标的优点&#xff1a; 灵活性&#xff1a;灵活地修改样式&#xff0c;例如&#xff1a;尺寸、颜色等轻量级&#xff1a;体积小、渲染快、降低服务器请求次数兼容性…

SQL ALTER TABLE 语句

&#x1f4d2;博客主页&#xff1a; ​​开心档博客主页​​ &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由开心档原创&#xff01; &#x1f4c6;51CTO首发时间&#xff1a;&#x1f334;2022年12月12日&#x1f334; ✉…

华硕编程竞赛11月JAVA专场 J题再见天空 题解

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

回归测试对比确认测试的区别

回归测试和确认测试是软件测试工作流程中的经常会做的两件事情&#xff0c;这两个环节也是代表软件测试的两个分类&#xff0c;那么他们之间的区别是什么&#xff1f;这篇文章咱们分析一下。回归测试与确认测试的区别&#xff1f;确认测试我们先说确认测试&#xff0c;它是软件…

表格解析 概览

表格解析发展至今&#xff0c;仍然是一项很年轻的研究领域&#xff0c;出现了大量解决方案&#xff0c;常用的技术包括&#xff1a;线检测、box检测、分割、多模态融合、GCN、img2seq。以下按我的理解梳理一下表格解析各个流派&#xff0c;从中了解这项任务背后所采用的技术。在…

28130-13-4,Val-Val-Val,H2N-VVV-OH

As trileucine, trivaline self-assembles into monolayers on highly ordered pyrolytic graphite (HOPG).三缬氨酸在高度有序的热解石墨(HOPG)上自组装成单层。 编号: 179127中文名称: 三肽Val-Val-Val英文名: Val-Val-ValCAS号: 28130-13-4单字母: H2N-VVV-OH三字母: H2N-Va…

算法:栈和队列的设计

一 用两个栈实现队列 1.1 题目描述 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&a…

1 数据可视化简介

1.1 可视化释义 人眼是一个高带宽的巨量视觉信号输入并行处理器&#xff0c;最高带宽为每秒100MB&#xff0c;具有很强的模式识别能力&#xff0c;对可视符号的感知速度比对数字或文本快多个数量级&#xff0c;且大量的视觉信息的处理发生在潜意识阶段。其中的一个例子是视觉突…

SpringCloud2.0

一、网站架构演变过程 从传统架构(单体应用) 到 分布式架构(以项目进行拆分) 到 SOA架构(面向服务架构) 到 微服务架构 传统架构&#xff1a; 其实就是SSH或者SSM&#xff0c;属于单点应用&#xff0c;把整个业务模块都会在一个项目中进行开发&#xff0c;分为MVC架构&#…

pip install下载报网络错误、pip报错,以及module ‘serial‘ has no attribute ‘Serial‘报错

pip install下载报网络错误 下载pip install serial时报错如图&#xff1a;这是由于下载的pip官网是国外网站&#xff0c;下载速度会比较慢。 解决办法&#xff1a;从国内镜像去下载 ​ pip install serial -i https://pypi.tuna.tsinghua.edu.cn/simple或&#xff1a;sudo p…

虚拟化与云计算的区别

虚拟化和云计算之间的区别对于业务来说是至关重要和必要的。对于许多公司和专业人士来说&#xff0c;两者都是一样的。虽然云计算使用了虚拟化&#xff0c;但是虚拟化和云计算不是一回事。他们处理各种规模的 IT 挑战&#xff0c;并在对业务产生不同程度影响的不同范围内运作。…

工作很迷茫,是继续留在大城市打拼,还是回老家躺平呢?

你有没有面对这样的选择&#xff1a;是回到老家过一眼望到头的舒服简单的日子&#xff0c;还是趁年轻留在大城市拼一把&#xff0c;突破自己的舒适圈&#xff0c;挑战更多的可能性。你做了怎样的选择&#xff1f;你后悔吗&#xff1f; 什么样的人适合去大城市呢&#xff1f; 1、…

人脸表情识别 实战项目

一个不知名大学生&#xff0c;江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2022.12.12 Last edited: 2022.12.12 目录 ​编辑 人脸表情识别 实战项目 简介 环境部署 数据准备 项目说明 传统方法 深度方法 网络设…

LeetCode 剑指 Offer 二叉树的最近公共祖先 | 解题思路分享

剑指 Offer 618 - II. 二叉树的最近公共祖先 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且…

基于Android的车位共享系统的设计

一、课题任务与目的 1. 课题背景 随着车辆越来越多&#xff0c;车位紧缺成为当前生活中最严重并且着急去解决的问题之一。本项目制作一款基于Android的车位共享系统用于缓解车位紧缺造成的压力。本次所开发的停车App是基于北京当前的交通状况为出发点的&#xff0c;让用…

Unity人工智能初学者指南

Unity人工智能初学者指南 使用 C# 在 Unity 游戏引擎中为游戏编写非玩家角色的实用指南 课程英文名&#xff1a;The Beginners Guide to Artificial Intelligence Unity 2022 此视频教程共13.5小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#xff0c;源码附件全…

Qt实现全局键盘事件监听器-Windows

Qt实现全局键盘事件监听器-Windows版&#x1f347; 文章目录Qt实现全局键盘事件监听器-Windows版&#x1f347;1、概述&#x1f348;2、实现效果&#x1f349;3、实现方式&#x1f34a;4、关键代码&#x1f34b;5、源代码&#x1f34c;更多精彩内容&#x1f449;个人内容分类汇…

分布式文件存储-FastDFS环境搭建

FastDFS简介 FastDFS是什么&#xff1f;我们这里可以看一下度娘的解释。FastDFS是一个开源的轻量级分布式文件系统&#xff0c;它对文件进行管理&#xff0c;功能包括&#xff1a;文件存储、文件同步、文件访问&#xff08;文件上传、文件下载&#xff09;等&#xff0c;解决了…

grid布局 笔记

这次给大家带来的是grid布局&#xff0c;之前听说过但没接触过&#xff0c;一起来学一下吧&#xff0c;提升一下css认知。 1、开启方式 给父级盒子开启grid布局 display: grid2、gap 间隙 所有盒子的行列间隙为10px gap: 10px行/列 colomn-gap: 20px;row-gap: 15px注意&#…

java计算机毕业设计ssm迎新系统pv83c(附源码、数据库)

java计算机毕业设计ssm迎新系统pv83c&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项…