堆排序----C语言数据结构

目录

引言

堆排序(Heap Sort)是一种基于比较 的排序算法,利用堆的数据结构来实现。它的时间复杂度为O(n log n),并且是原地排序算法,不需要额外的存储空间,这使得它在空间复杂度方面具有优势。

堆排序的关键在于构建和维护堆的性质。虽然堆排序的时间复杂度较好,但在实际应用中,由于其不具备插入和删除操作的优势,因此在一些特殊方面很少被选择。

堆排序的实现

堆排序实现的基本思路为:

  1. 建堆
    升序:建大堆
    降序:建小堆
  2. 利用堆删除思想来进行排序
    建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

堆的向下调整算法

从给出的 一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。

向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

如图:

c 复制代码
void Swap(int* a, int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}

void AdjustDwon(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;
	}
}

在一个堆中,根节点从0开始编号,下标为 i(i > 0) 的结点的左右孩子结点及父结点的下标:

左孩子:2i(i>0)

右孩子:2i+1

父节点: (i-1)/2

根据树的父子结点的联系来确定数组下标

c 复制代码
void HeapSort(int* a, int n)
{
	//起始i用n-1是数组的最后一个为n-1,起始i为最后一个元素的父节点
	for (int i = (n - 1 - 1) / 2;i >= 0;i--)
	{
		AdjustDwon(a, n, i);
	}
	int end = n - 1;
	//建好大堆,将最大值交换置数组的最后,然后排出最后一个元素,对前n-1的数组进行建堆
	while(end>0)
	{
		Swap(&a[0], &a[end]);
		AdjustDwon(a, end, 0);
		end--;
	}
}

对排序的时间复杂度

建堆的时间复杂度:

在堆排序中,首先需要将待排序的序列构建成一个最大堆。构建最大堆的时间复杂度是O(n),其中 n 是待排序序列的长度。这是因为我们只需要对具有父子关系的一半节点进行堆化操作,而这一半节点通常是 n/2。

排序过程的时间复杂度:

堆排序的排序过程包括了 n-1 次交换和堆调整的操作。每次交换涉及到堆顶元素与末尾元素的交换,然后对剩余的 n-1 个元素进行堆调整。堆调整的时间复杂度为O(log n)。因此,排序过程的总时间复杂度为 O((n-1) * log n),约等于O(n log n)。

总体时间复杂度:

将建堆和排序过程的时间复杂度结合起来,堆排序的总体时间复杂度为 O(n + n log n)。在大 O 表示法中,通常会忽略掉低阶项和常数系数,因此可以简化为 O(n log n)。

堆排序的时间复杂度是相对较好的,且具有原地排序的特点。然而,需要注意的是,堆排序在实际应用中可能会因为其不具备稳定性(相同元素的相对位置可能发生变化)和对缓存的不友好等原因而被其他算法替代。

相关推荐
Miraitowa_cheems3 小时前
LeetCode算法日记 - Day 73: 最小路径和、地下城游戏
数据结构·算法·leetcode·职场和发展·深度优先·动态规划·推荐算法
野蛮人6号3 小时前
力扣热题100道之560和位K的子数组
数据结构·算法·leetcode
Swift社区4 小时前
LeetCode 400 - 第 N 位数字
算法·leetcode·职场和发展
fengfuyao9854 小时前
BCH码编译码仿真与误码率性能分析
算法
Kratzdisteln4 小时前
【C语言】Dev-C++如何编译C语言程序?从安装到运行一步到位
c语言·c++
小白不想白a5 小时前
每日手撕算法--哈希映射/链表存储数求和
数据结构·算法
剪一朵云爱着5 小时前
力扣2080. 区间内查询数字的频率
算法·leetcode
落日漫游5 小时前
数据结构笔试核心考点
java·开发语言·算法
Doro再努力5 小时前
数据结构04:力扣顺序表3道例题解题思路与代码实现
c语言·数据结构
疯狂吧小飞牛5 小时前
Lua C API 中的注册表介绍
java·c语言·lua