左偏树&斜堆
表示学这些东西是为了为学可持久化treap铺垫。
但实际上这是一种很鸡肋的数据结构。
用来解决什么问题?
就是在堆的基础上,支持
解决这个问题的似乎还有个斐波拉契堆,不懂……
数据结构核心
左偏树
这不是一个完全二叉树,它就是一个二叉树。
性质和堆一样,对于小根堆,爸爸都比儿子小。
但它多了一个dist,x节点的dist表示x的后代中没有左或右节点到x的最短距离。
若
左偏树有个性质,叫左偏性质:
这个性质很有用,可以使树高小一些,因为合并是在右边进行的。
如果要合并A、B,设
回溯的时候,如果不满足左偏性质,就进行交换。最后更新dist。
struct Leftist_Tree
{
struct Node
{
int l,r;
int val,dist;
} d[100001];
int cnt;
int newnode(int _val)
{
d[++cnt].val=_val;
d[cnt].dist=1;
}
int merge(int a,int b)
{
if (!a)
return b;
if (!b)
return a;
if (d[a].val>d[b].val)
swap(a,b);
d[a].r=merge(d[a].r,b);
if (d[d[a].r].dist>d[d[a].l].dist)
swap(d[a].l,d[a].r);
d[a].dist=d[d[a].r].dist+1;
return a;
}
}
斜堆
和左偏树差不多,但是不需要记录dist值,没有左偏性质,只是在回溯时直接交换左右子树。这就是期望!
虽然比左偏树简单一点,但左偏树比它更优。