最大最小堆(min-max heap)

最大最小堆是一种结合了最大堆和最小堆特性的数据结构,能够在同一个数组中同时支持最大值和最小值的快速查询与删除。其独特之处在于,节点的排列规则使得根节点是最小值,而根节点的两个儿子中较大的那个是最大值。主要操作包括上移和下移,操作时间复杂度为O(logn)。在实际项目中,最大最小堆能有效节省空间,替代两个独立的二叉堆或平衡树来实现相似功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做项目的时候听说了最大最小堆这种数据结构,于是就来学习一下。

最大最小堆算是二叉堆的变形,结构与二叉堆类似,只是节点的排列顺序有所不同。相较于二叉堆,最大最小堆能够同时支持最大值或最小值的查询(O(1)O(1)O(1))和删除(O(log⁡n)O(\log n)O(logn))操作。

相较于用两个二叉堆或用平衡树实现相同的功能,最大最小堆唯一的优势大概就是只需要开一个大小为 nnn 的数组。

性质

最大最小堆的结构和二叉堆一样,都是一棵满二叉树。若令根节点深度为 000,则满足在以深度为偶数的节点为根的子树中,根节点为子树的最小值,否则为子树的最大值。上述条件等价于,深度为偶数的点小于父亲且大于祖父,深度为奇数的点大于父亲且小于祖父(假设键值两两不同)。

那么根节点就是最小值,根节点两个儿子的较大值就是最大值。

操作

主要的操作分为上移和下移,时间复杂度均为 O(log⁡n)O(\log n)O(logn)

min_shift_down(index) 函数在假设编号为 index 的节点的子树中,除根以外均满足最大最小堆的性质,且根节点的深度为偶数,并把根节点下移调整来满足性质。

void min_max_heap::min_shift_down(int index)
{
   
   
	if (!has_child(index)) return;	//若没有孩子就退出
	//将根节点调整为它和两个孩子中的较小值,调整后子树仍满足性质
	int c = min_child(index);
	if (data[c] < data[index]) swap(c, index);
	//根据孙子情况讨论
	if (!has_grandchild(index)) return;
	int grand = min_grandchild(index);
	if (data[index] > data[grand]) swap(index, grand), min_shift_down(grand);
}

min_shift_up(index) 函数在假设整个堆若不看编号为 index 的节点,均满足最大最小堆的性质,且 index 的深度为偶数,并把 index 上移调整来满足性质。

void min_max_heap::min_shift_up(int index)
{
   
   
	if (!has_parent(index)) return;	//若没有父亲则退出
	if (!has_grandparent(index))	//若没有祖父,则只需要让父亲满足条件
	{
   
   
		int p = parent(index);
		if (data[p] < data[index]) swap(p, index);
	}
	else		//否则需要根据祖父情况进行讨论
	{
   
   
		int grand = grandparent(index);
		//若祖父不满足性质,则交换后递归处理
		if (data[index] < data[grand]) swap(index, grand), min_shift_up(grand);
		else
		{
   
   
			int p = parent(index);
			//若父亲不满足性质,则交换后递归处理
			if (data[index] > data[p]) swap(index, p), max_shift_up(p);
		}
	}
}

代码

洛谷 P3378 【模板】堆

#include<bits/stdc++.h>
using namespace std;

class min_max_heap
{
   
   
	public:
		vector<int> data;
		bool
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值