堆排序详细理解

目录

一、前备知识

二、建堆

2.2.1 向上调整算法建堆

2.2.2 向下调整算法建堆

三、排序

3.1 常见问题 

3.2 思路

3.3 源码


一、前备知识

详细图解请点击:二叉树的顺序实现-堆-CSDN博客

本文只附上向上/向下调整算法的源码

//交换
void Swap(int* p, int* q)
{
	int tmp = *p;
	*p = *q;
	*q = tmp;
}
//向下调整算法
void AdjustDown(int* a, int n, int parent)
{
	//左孩子的下标
	int child = parent * 2 + 1;
	while (child<n)
	{
		//找到两个孩子中较小的孩子-假设法
		if (child + 1 < n && a[child + 1] < a[child])
		{
			child++;
		}
		if (a[parent] > a[child])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//向上调整算法
void AdjustUp(int* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

二、建堆

堆排序堆排序,先有堆才能排序,所以排序的第一步是要将一个一般的数组建成堆。

注:由于建大堆还是小堆仅仅取决于自定的大小于号,本文下述建堆都以小堆为例

2.2.1 向上调整算法建堆

思路:

  1. 单一的一个结点可以看成一个堆
  2. 后续的所有结点都可以看作是插入结点

所以只需要循环插入所有后续结点即可

void BuildHeap1(int* a, int n)
{
	//把根节点看作是堆,剩下的结点看作插入结点,开始依次插入
	for (int i = 1; i < n; i++)
	{
		AdjustUp(a, i);
	}
}

2.2.2 向下调整算法建堆

错误思路:

向下调整算法要求左右子树必须为大/小堆,所以从根节点开始结点开始建堆的做法是错误的

正确思路:

上文说:单一的一个结点可以看成一个堆所以从最后一个叶子节点的父节点开始向下调整,不断循环所有父节点,就可以保证他的左右子树都是堆。

void BuildHeap2(int* a, int n)
{
	//从最后一个叶子结点的父结点开始调
	for (int i = ((n - 1) - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}
}

三、排序

3.1 常见问题 

  • 为什么建堆后依然还要排序?

        大堆/小堆的定义注定了堆仅仅能保证父节点大于孩子结点,无法保证孩子结点按照大于/小于的次序严格排列!!!

  • 升序建小堆,降序建大堆的思路是否可行?
  1. 升序建小堆:首先对 n 个数建小堆,选出最小的数,接着对剩下的 n-1 个数建小堆,选出第二小的数,不断重复上述过程。若用向上调整算法可行但时间复杂度太高,若使用向下调整算法时,对n-1个调整就会发现:原先的孩子父亲关系全乱,不可行。
  2. 降序建大堆:首先对 n 个数建小堆,选出最小的数,接着对剩下的 n-1 个数建大堆,选出第二大的数,不断重复上述过程。使用向下调整算法时,对n-1个调整就会发现:原先的孩子父亲关系全乱,不可行。

3.2 思路

  1. 本质上是堆删除的思路。利用堆的特性,无论是大堆还是小堆,根节点的值一定是最大/小的数。这样每进行一次调整,就会选择出最小/大,次小/大......便可以实现排序。
  2. 为了防止出现父子关系乱序的问题,将每次找到的最值放在堆的末位置,对前n-1个元素进行向下调整,便可以完美解决排序问题
  3. 由此可以总结:升序建大堆,降序建小堆

由此,我们可以归纳出堆排序算法的步骤:

1. 把无序数组构建成二叉堆。

2. 循环删除堆顶元素,移到数组尾部,调节堆产生新的堆顶。

3.3 源码

//降序建小堆
void HeapSortDown(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[0], &a[end]);	// 将堆顶元素和堆中最后一个元素交换,把最大的数(堆顶)放到最后
		AdjustDown(a, end, 0);
		end--;					// 调整前n-1个元素
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java中回调与Timer类的使用

回调&#xff1a;回调&#xff08;callback)是一种常见的程序设计模式。在这种模式中&#xff0c;可以指出某个特定事件发生时应该采取的动作。 Timer类&#xff1a;java.swing包中的Timer类&#xff0c;可以使用它在给定的时间间隔时发出通告。如程序中有一个时钟&#xff0c…

水位监测站的工作原理

TH-SW2在雨季&#xff0c;河道和湖泊的水文信息监测对于防洪减灾、水资源管理和环境保护等方面具有至关重要的意义。水文监测站作为实现这一目标的基础设施&#xff0c;发挥着关键作用。水文监测站是观测及搜集河流、湖泊、水库等水体的水文、气象资料的基层水文机构。在雨季&a…

算法与数据结构:红黑树

ACM大牛带你玩转算法与数据结构-课程资料 本笔记属于船说系列课程之一&#xff0c;课程链接&#xff1a; 哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep66799?csourceprivate_space_class_null&spm_id_from333.999.0.0 你也可以选择购买『船说系列课程-年度会…

【计算机毕设】基于Spring Boot的课程作业管理系统 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 课程作业管理系统旨在为教师和学生提供一个便捷的平台&#xff0c;用于发布、提交和评定课程作业。本系统旨在提高作业管理的效率&#xff0c;促进教…

NetMizer 日志管理系统前台RCE漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 一、产品介绍 NetMizer日志管理系统是一个与NetMizer流量管理设备配合…

nginx的安装002

之前001讲述了nginxyum安装现在讲一下nginx如何本地离线安装 操作系统&#xff1a; CentOS Stream 9 操作步骤&#xff1a; 首先访问nginx官网&#xff0c;下载。 用wget命令下载&#xff0c; [rootlocalhost ~]# wget -c https://nginx.org/download/nginx-1.26.0.tar.gz …

【网络原理】HTTP|认识请求“报头“|Host|Content-Length|Content-Type|UA|Referer|Cookie

目录 认识请求"报头"(header) Host Content-Length Content-Type User-Agent(简称UA) Referer &#x1f4a1;Cookie&#xff08;最重要的一个header&#xff0c;开发&面试高频问题&#xff09; 1.Cookie是啥&#xff1f; 2.Cookie怎么存的&#xff1f; …

在PostGIS中检查孤线(Find isolated lines in PostGIS)

场景 在PostGIS中有一张线要素表,需要检查该表中的孤线,并且进行自动纠正的计算。 其中孤线定义为两端端点都不在任何其他线的顶点上。 本文介绍在PostGIS中的线要素点,通过函数计算指定线要素表中的孤线,并计算最接近的纠偏位置。 In PostGIS, there is a table of line …

07-操作元素(键盘和鼠标事件)

在前面的文章中重点介绍了一些元素的定位方法&#xff0c;定位到元素后&#xff0c;就需要操作元素了。本篇总结了web页面常用的一些操作元素方法&#xff0c;可以统称为行为事件。 一、简单操作 点击按钮&#xff08;鼠标左键&#xff09;&#xff1a;click()清空输入框&…

git冲突

git冲突的产生&#xff1a; 首先用户A新建一个文件conflict&#xff0c;并在里面添加内容 然后通过add,commit,push将该文件上传到远端仓库 然后用户B通过pull将程序拉下来之后&#xff0c;也在这个文档里面进行编辑&#xff0c;并且内容不一样 如果这个时候其中一个人push&…

PAT-1004 成绩排名(java实现)

这一关感觉还没第三关难&#xff0c;思路很清晰 题目 1004 成绩排名 读入 n&#xff08;>0&#xff09;名学生的姓名、学号、成绩&#xff0c;分别输出成绩最高和成绩最低学生的姓名和学号。 输入格式&#xff1a; 每个测试输入包含 1 个测试用例&#xff0c;格式为 第 1 行…

加密金字塔的秘密:「高层」的回报你无法想象

原文标题&#xff1a;《The Secrets of the Crypto Pyramid!》 撰文&#xff1a;DUO NINE⚡YCC 编译&#xff1a;Chris&#xff0c;Techub News 本文来源香港Web3科技媒体&#xff1a;Techub News 意外成为一名 KOL 让我有机会深入了解这个领域的运作机制。在这个行业的幕后…

优化基础(二):线性组合、仿射组合、锥组合、凸组合、线性集合、仿射集合、锥集合、凸集合的理解

文章目录 前言组合线性组合 (linear combination)仿射组合 (affine combination)锥组合 (conic combination)凸组合 (convex combination) 集合仿射集合凸集合 练习&#xff1a;哪个图形是凸的&#xff0c;哪个是仿射的&#xff1f;参考资料 前言 组合侧重于描述由一些基点生成…

ai虚拟主播自动切换的实现

前段时间,看到b站突然冒出很多ai主播,输入数字切换小姐姐.感觉挺有趣.思考了以下决定手动实现一下. 然后就陷入长达5天的踩坑中 由于是自建的webrtc服务器,很自然的想直接收流转发,这也是最优的方案, 然而实际上遇到许多不是很友好的bug, 然后再想使用rtp转发,依然不理想. 最后…

使用香橙派 AI pro 开发板生成卡通版的东契奇

引言 AI应用如火如荼&#xff0c;而嵌入式设备与AI的结合也是不可或缺的重要场景。香橙派 AI pro 开发板正是面向嵌入式AI场景而生。 这篇文章记录了对香橙派 AI pro开发板的试用体验。介绍了开发板的基础操作&#xff0c;以及对其中一个AI应用样例的体验&#xff0c;初步感受…

Docker安装Redis(云服务器)

准备&#xff1a; 在云服务器中开启6370端口号 docker run -d --name redis -p 6379:6379 redis 这条命令使用docker运行一个名为"redis"的容器&#xff0c;映射容器的6379端口到主机的6379端口&#xff0c;并且使用redis镜像来运行容器。REDIS是一个开源的内存数据…

记 Codes 开源免费研发管理平台 —— 日报与工时融合集中式填报的创新实现

继上一回合生成式全局看板的创新实现后&#xff0c;本篇我们来讲一讲日报与工时融合集中式填报的创新实现。 市面上所有的研发管理软件&#xff0c;大多都有工时相关功能&#xff0c;但是却没有日报功能&#xff0c;好像也没什么问题&#xff0c;但是在使用过程中体验非常不…

RandLA-Net 训练自定义数据集

https://arxiv.org/abs/1911.11236 搭建训练环境 git clone https://github.com/QingyongHu/RandLA-Net.git搭建 python 环境 , 这里我用的 3.9conda create -n randlanet python3.9 source activate randlanet pip install tensorflow2.15.0 -i https://pypi.tuna.tsinghua.e…

IDEA 安装BPMN插件-Activiti BPMN visualizer

IDEA安装BPMN插件 idea 18版本之前idea 18版本之后安装插件 推荐使用 Activiti BPMN visualizer插件注意 创建bpmn文件使用可视化面板 在可视化面板中右键可创建各种节点每个节点上都有连线 删除 设置的按钮 保存图片 idea 18版本之前 可以通过搜索插件actiBPMN直接安装 idea…

VBA代码解决方案第十四讲 如何利用VBA检查单元格中是否含有公式

《VBA代码解决方案》(版权10028096)这套教程是我最早推出的教程&#xff0c;目前已经是第三版修订了。这套教程定位于入门后的提高&#xff0c;在学习这套教程过程中&#xff0c;侧重点是要理解及掌握我的“积木编程”思想。要灵活运用教程中的实例像搭积木一样把自己喜欢的代码…