【算法之排序篇】 堆排序详解!(源码+图解)


🎥 屿小夏 : 个人主页 🔥个人专栏 : 算法---排序篇 🌄 莫道桑榆晚,为霞尚满天!

文章目录

📑前言

什么是堆排序?堆在原数据结构上是怎么实现堆排从而使数据有序的?

🌤️堆的理论概念

☁️堆的思想

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

🌤️堆的代码具体实现

☁️图解

☁️源码

c 复制代码
//堆排序
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[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
			break;
	}
}
void HeapSort(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--;
	}
}

☁️源码剖析

  1. AdjustDown 函数用于维护堆的性质,即父节点的值大于或等于其子节点的值。它从一个节点开始,将它与其子节点比较,并交换它和较大子节点的值,然后继续向下递归调整,直到满足堆的性质。
  2. HeapSort 函数首先通过遍历数组,从最后一个非叶子节点开始,调用 函数,逐步构建最大堆。AdjustDown
  3. 然后,将堆的根节点(最大值)与数组的最后一个元素交换,将最大值放到正确的位置。
  4. 接着,重新调用 函数,将剩余元素重新构建成最大堆,排除已排序的部分。AdjustDown
  5. 重复步骤 3 和 4,直到整个数组有序。

🌤️堆排序特性

☁️不稳定排序

堆排序是一种不稳定的排序算法,因为在堆的调整过程中可能会改变相同值的元素的相对顺序。

☁️时间复杂度

堆排序的平均和最坏时间复杂度均为 O(n*log(n)),其中 n 是待排序元素的数量。

☁️原地排序

堆排序是一种原地排序算法,不需要额外的辅助存储空间,只需要在原数组上进行元素的交换和调整。

☁️不适用于小数据集

堆排序的性能相对较好,但对于小规模的数据集来说,其常数项较大,不如快速排序等算法效率高。

☁️堆的构建和调整

堆排序的核心是构建堆(通常是最大堆),然后反复将堆顶元素(最大值)与堆中的最后一个元素交换,并调整堆,使剩余部分仍然满足堆的性质。

☁️适用于外部排序

堆排序也适用于外部排序问题,其中数据无法全部加载到内存中,需要逐块处理数据。

☁️稳定性

堆排序通常不是稳定的排序算法,即相同值的元素在排序后的相对位置可能会改变。如果需要稳定性排序,应该选择其他算法,如归并排序。

☁️最好、最坏和平均情况

堆排序的时间复杂度在任何情况下都是 O(n*log(n)),因此具有稳定的性能。

🌤️全篇总结

堆排序的主要优点在于它具有稳定的时间复杂度 O(n*log(n)),适用于大规模数据集的排序,而且是一种原地排序算法,不需要额外的空间。但它并不适用于小规模数据集,因为其常数项较大。堆排序也不是稳定排序,即相同值的元素在排序后的相对位置可能会改变。

☁️相信聪明的你肯定已经学会堆排了吧。

看到这里希望给博主留个:👍点赞🌟收藏⭐️关注!
你们的三连就是博主创作的最大动力!

相关推荐
振鹏Dong23 分钟前
字符串——面试考察高频算法题
java·数据结构·算法
染指111033 分钟前
6.第二阶段x64游戏实战-分析人物状态
开发语言·汇编·windows·游戏·游戏逆向·x64dbg·x64游戏
北冥有鱼被烹41 分钟前
【代码模板】C语言如何修改文件权限?读写执行权限对应值是多少?(chmod(“./a.out“, 0741);bit 2 1 0表示 读 写 执行)
c语言
forestsea1 小时前
Java虚拟机面试题:内存管理(中)
java·开发语言
longlong int1 小时前
【每日算法】Day 17-1:位图(Bitmap)——十亿级数据去重与快速检索的终极方案(C++实现)
开发语言·c++·算法
欧宸雅1 小时前
Perl语言的文件系统
开发语言·后端·golang
写代码的小王吧1 小时前
【安全】Java幂等性校验解决重复点击(6种实现方式)
java·linux·开发语言·安全·web安全·网络安全·音视频
泛舟起晶浪1 小时前
大衣的旅行--前缀和+二分
数据结构·算法
淘源码d2 小时前
如何运用C#.NET快速开发一套掌上医院系统?
开发语言·c#·.net·源码·掌上医院
一个程序员(●—●)2 小时前
xLua环境控制+xLua的Lua调用C#的1
开发语言·unity·c#·lua