可并堆(左偏树)简单学习

这篇博客介绍了可并堆,特别是左偏树作为一种优化合并操作的数据结构。相比于传统的二叉堆,左偏树在合并两个堆时能提供更好的时间复杂度。文章详细讨论了左偏树的特性,并提供了洛谷平台上相关问题的实践例子,如P3377、P1456和P1552,以帮助读者理解其在实际问题中的应用。
摘要由CSDN通过智能技术生成

通常我们使用的二叉堆,是用一个数组实现的完全二叉树,对于查询有O(1)复杂度,对于插入、删除有O(logn)复杂度

而且常数比较小,是一个比较优秀的数据结构


但是。

当我们需要合并两个堆的时候,用普通的二叉堆就显得吃力了,时间复杂度达到log(n+m)

这个时候可并堆这种数据结构就出现了。而在其中,尤以左偏树代码复杂度和时间复杂度综合得比较优秀


左偏树

在介绍左偏树之前,得先引入一个叫距离(d)的概念:
在左偏树中,一个节点u的距离,等于u到它和叶子节点中最近的左右儿子不满的节点【也就是可插入的节点】的距离。

然后左偏树是这样定义的:
左偏树是左儿子距离不小于右儿子距离的二叉堆。

这样子有什么用呢?
当插入节点时,只需往右儿子插入,可降低插入的时间复杂度。

实现

首先每个节点这样声明:
struct LT{
	int v,l,r,d;
	LT() {l=r=d=0;}
}e[maxn];



左偏树的所有操作都是以合并操作为基础的:
对于根节点为u和v两个左偏树是这样合并的:
1、如果其中有空节点,直接返回另一个非空结点
2、选择节点值较小的作为根节点,然后合并根节点的右儿子和另一个节点【merge(root.r,v)】【递归】
3、维护根节点的距离。我们设空节点的距离为-1,那么根节点的距离=右儿子距离+1

C++代码:

int merge(int a,int b){
	if(!a) return b;
	if(!b) return a;
	if(e[b].v<e[a].v) a^=b^=a^=b;
	e[a].r=merge(e[a].r,b);
	if(e[e[a].l].d<e[e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值