【算法学习】左偏树

左偏树

左偏树是一种可以快速合并的可并堆,相对于普通的二叉堆,左偏树的合并可以做到log(p1+p2)log(p_1 + p_2)log(p1+p2),是一种十分优秀的数据结构。

性质

左偏树是一种可并堆的实现,是一颗二叉树,它除了有二叉树的左右儿子,还有2个属性,键和距离。下面是左偏树的一些基本性质。

  1. 节点的键值小于或等于左右子节点的键值。这是左偏树的堆性质。
  2. 节点的左子节点的距离不小于右子节点的距离。
  3. 节点的距离等于它的右子节点距离加一。
  4. 若左偏树的距离为一定值,则节点数最少的左偏树是完全二叉树。
  5. 若一棵左偏树的距离为kkk,则这棵左偏树至少有2k+1−12^{k + 1} -12k+11个节点。
  6. 一棵NNN个节点的左偏树距离最多为⌊log(N+1)−1⌋\lfloor log(N+1) -1 \rfloorlog(N+1)1

操作

以下操作均维护一个小根堆,如果涉及到两个左偏树,那么树根分别为x,yx,yx,y,否则树根为xxx

数据结构如下:

struct node {
   
   
    int val, lc, rc, dis, fa;
}tree[nmax];

val表示值,lc合rc分别表示左子树合右子树,dis表示节点的距离,fa表示父亲(根据实际情况,有些题目不需要)。

合并

合并是最基本的操作,根据性质1,可以设计出以下算法。

  1. 简单情况,如果xxx为空树,直接返回yyy;如果yyy为空树,直接返回xxx
  2. 如果不满足1,继续判断。如果xxx的根节点val大于yyy根节点的val,那么swap(xxx, yyy),目的是保证把大的合并到小的上。
  3. yyy的根和xxx的右子树判断是否满足2的规则,递归合并,缩小规模,直到一个叶子节点,那么直接修改tree[x].rc=ytree[x].rc = ytre
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值