排序——堆排序

一、概念及结构

堆是一种特殊的树形数据结构,通常表现为一棵完全二叉树,是用二叉树的顺序存储方式来存储元素的。堆分为小堆和大堆

1.1 小堆

父结点小于子结点,但是父结点下面的两个子结点没大小区分。

1.2 大堆

父结点大于子结点,但是父结点下面的两个子结点没大小区分。

二、建堆(小堆示例)

2.1 向上调整建堆

适用于一边插入一边建堆的情况。插入节点后,找到它的父结点,让父结点与它进行比较,如果小于它则退出,如果大于则交换位置,重复上述操作直至循环结束或跳出循环。

cpp 复制代码
void AdjustUp(int* arr, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (arr[child] < arr[parent])//改为 > 建大堆
		{
			Swap(&arr[child], &arr[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
        {
            break;
        }
	}
}

注:Swap是交换位置函数。

cpp 复制代码
void Swap(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

2.2 向下调整建堆

适用于对父节点进行调整。先找到较小的那个孩子,让该孩子与它进行比较,如果孩子大于它则退出,如果小于则交换位置,重复上述操作直至循环结束或跳出循环。

cpp 复制代码
void AdjustDown(int* arr, int n, int parent)
{
	int child = (parent * 2) + 1;//先默认找到左孩子
	while (child < n)
	{
        //判断左孩子是否大于右孩子,child + 1 < n防止非法访问
		if (child + 1 < n && arr[child + 1] < arr[child])
			child++;

		if (arr[parent] > arr[child])
		{
			Swap(&arr[parent], &arr[child]);
			parent = child;
			child = (parent * 2) + 1;
		}
		else
        {
            break;
        }
	}
}

三、TOPK问题

TOPK问题:即求数据结合中前K个最大的元素或者最小的元素。一般来说数据量比较大。如果有一个数组,数组里有N个数据,我们要找最大的前K个数据,要怎么做呢?

3.1 法一:

先整体建立一个大堆,然后让根节点与该堆的最后一个节点交换,然后拿取该堆最后的结点,再让根结点向下调整。重复上述操作K次。

cpp 复制代码
void Heapsort(int* a, int n)
{
	int k = 0;
	scanf("%d", &k);
	for (int i = 0; i < n; i++)
		AdjustUp(a, i);

	while (k--)
	{
		Swap(&a[n - 1], &a[0]);
		AdjustDown(a, n - 1, 0);
		n--;
	}
}

3.2 法二:

先从数组中取前k个数建立一个小堆,然后遍历后面的元素,后与堆顶元素比较,如果大于则进行交换,然后向下调整。最后拿出该堆即可。

cpp 复制代码
void Heapsort(int* a, int n)
{
	int k = 0;
	scanf("%d", &k);
	for (int i = (k - 2) / 2; i >= 0; i--)
		AdjustDown(a, k, i);

	for (int i = k; i < n; i++)
	{
		if (a[i] > a[0])
		{
			Swap(&a[i], &a[0]);
			AdjustDown(a, k, 0);
		}
	}
}

(k - 2) / 2是为了拿到该堆中最后一个父节点的下标:子节点的下标求出父节点的下标的公式是 (i - 1) / 2 ,但是这里 k - 1 先当于是最后一个孩子节点的下标所以是 (k - 2) / 2。

相关推荐
土司大王7 小时前
LeetCode hot100——对称二叉树
算法·leetcode·职场和发展
sali-tec7 小时前
C# 基于OpenCv的视觉工作流-章106-差值追踪
图像处理·人工智能·opencv·算法·计算机视觉
Navigator_Z7 小时前
LeetCode //C - 1208. Get Equal Substrings Within Budget
c语言·算法·leetcode
手写码匠7 小时前
Dify 多 Agent 工具权限与安全沙箱实战:让智能体“有能力,但不越权“
人工智能·深度学习·算法·aigc
黎阳之光8 小时前
打破堆场感知黑盒:黎阳之光视频孪生,构建港口码头网格化透明管控新体系
大数据·人工智能·算法·安全·数字孪生
大模型码小白8 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
sel_99 小时前
【多轮对话论文导读(三)】多轮对话与Agent论文阅读笔记:用户模拟、轨迹生成与长期记忆
论文阅读·人工智能·笔记·深度学习·算法·机器学习
Asize9 小时前
438. 找到字符串中所有字母异位词
算法
Asize9 小时前
283. 移动零
算法
船厂电气自动化ai大模型11 小时前
AI大模型与数学·第57课 傅里叶全套工具链综合实战:串联级数/连续变换/DFT/FFT,图像、音频、扩散模型完整例题
数据结构·人工智能·深度学习·算法·机器学习