可并堆是啥
给你两个优先队列,要你合并这两个优先队列,而且还要保证合并后符合优先队列的性质,时间复杂度要限制在 log ( s 1 + s 2 ) \log (s_1+s_2) log(s1+s2)之内。
怎么做?现在普通的堆已经满足不了要求了。
这个时候,就要用一种神奇的数据结构:左偏树了。
(二项堆,斐波那契堆不在本文的考虑范围内)
左偏树
顾名思义,左偏树就是一棵向左偏的树(逃
我们定义一个节点为外节点,当且仅当这个节点的左子树和右子树中的一个是空节点。(注意外节点不是叶子节点)
一个点的距离,被定义为它子树中离他最近的外节点到这个节点的距离(这与树的深度不同)
(图片来源:百度百科)
如图,蓝色的数字就是距离。
我们规定,空节点的距离为 − 1 -1 −1。
一个合格的左偏树,必须满足下列性质:
-
性质1. 左偏树中,任何一个节点的父节点的权值都要小于等于这个节点的权值(堆性质)
v a l f a i < v a l i val_{fa_i}<val_i valfai<vali
这告诉我们:左偏树很像堆,如果长成了完全二叉树,那就是一个堆。
-
性质2. 左偏树中任意一个节点的左儿子的距离一定大于等于右儿子的距离(左偏性质)
d i s t l s i ≥ d i s t r s i dist_{ls_i}\ge dist_{rs_i} distlsi≥distrsi
需要注意的一点:左偏指的不是左右儿子的大小,因此如果左儿子是一个点,而右儿子是一条很长的链,那也是满足要求的左偏树。
-
推论1. 左偏树中任意一个节点的距离为其右儿子的距离 + 1 +1 +1。
d i s t i