众所周知,从AVL树中删除可能会导致多个节点最终失去平衡。我的问题是,最小尺寸的AVL树是什么,需要2次旋转(我假设左右或左右旋转是1次旋转)?我目前有一个包含12个节点的AVL树,其中删除会导致2次旋转。我的AVL树按此顺序插入:
8,5,9,3,6,11,2,4,7,10,12,1。
如果删除10,则9变得不平衡并发生旋转。在这样做时,8变得不平衡并且发生另一次旋转。是否有一个较小的树,删除后需要2次旋转?
在阅读了jpalecek的评论之后,我真正的问题是:给定一些常数k,删除1次后具有k个旋转的最小尺寸AVL树是什么?
答案 0 :(得分:3)
在最坏的情况下,四个节点的树需要单个旋转。最坏情况下的删除次数会随着列表中的每个术语而增加:4,12,33,88,232,609,1596,4180,10945,28656 ......
这是Sloane's A027941,是一个Fibonacci类型序列,可以使用N(i)=1+N(i-1)+N(i-2)
生成i>=2, N(1)=2, N(0)=1
。
要知道为什么会这样,首先请注意,旋转不平衡的AVL树会使其高度降低一,因为它的较短的腿会因长腿而延长。
当从AVL树中删除节点时,AVL算法会检查所有已删除节点的祖先以进行潜在的重新平衡。因此,为了回答您的问题,我们需要识别具有给定高度的最小节点数的树。
在这样的树中,每个节点都是叶子或平衡因子为+1或-1:如果节点的平衡因子为零,则意味着可以在不触发重新平衡的情况下删除节点。我们知道重新平衡可以缩短树木。
下面,我展示了一组最坏情况的树。您可以看到,在序列中的前两个树之后,每个树都是通过连接前两个树构建的。您还可以看到每个树中的每个节点都是叶子或具有非零平衡因子。因此,每棵树的节点数都有最大高度。
对于每棵树,在最坏的情况下,左子树中的移除将导致旋转,最终将该子树的高度减少一。这样可以平衡整个树。另一方面,从右子树中移除节点可能最终使树不平衡,导致根的旋转。因此,正确的子树是最重要的。
在最坏的情况下,您可以验证树(c)和树(d)在移除时有一次旋转。
树(c)在树(e)中显示为右子树,而树(d)在树(f)中显示为右子树。当在树(c)或(d)中触发旋转时,这会缩短树,从而导致树(d)和(f)中的根旋转。显然,序列仍在继续。
如果计算树中的节点数,则与原始语句匹配并完成校样。
(在下面的树中删除突出显示的节点将导致新的最大旋转次数。)
答案 1 :(得分:1)
我不擅长证明,我确信下面有很多漏洞,但也许它会激发一些积极的东西。
要在删除节点后在最小化的AVL树上实现k旋转,必须满足以下条件:
使用以下等式计算最小化树的节点的高度和数量。
设H(k)=受k旋转影响的树的最小高度。
H(k) = 2k + 1, k > 0
设N(h)=高度为h的(最小节点)AVL树中的节点数。
N(0) = 0
N(1) = 1
N(h) = N(h-1) + N(h-2) + 1, h > 1
设F(k)=受k个旋转影响的树中的最小节点数。
F(k) = N(H(k))
(例如:)
k = 1, H(k) = 4, N(4) = 7
k = 2, H(k) = 6, N(6) = 20
删除只能导致具有4个或更多节点的树的旋转。
在删除时发生1次旋转的最小子树是4个节点,其高度为3.删除短边节点将导致旋转。同样,删除根节点,使用短边上的节点作为替换将导致旋转。树的配置方式无关紧要:
B B Removal of A or replacement of B with A
/ \ / \ results in rotation. No rotation occurs
A C A D on removal of C or D, or on replacement
\ / of B with C.
D C
C C Removal of D or replacement of C with D
/ \ / \ results in rotation. No rotation occurs
B D A D on removal of A or B, or on replacement
/ \ of C with B.
A B
从4节点树中删除会生成高度为2的平衡树。
.
/ \
. .
要实现第二次旋转,目标树必须具有高度为4的兄弟,因此根的平衡因子为+/- 1(因此高度为5)。如果受影响的树位于父节点的右侧或左侧,并且兄弟树的布局也不重要(也就是说,H4的H3子节点可以在左侧或右侧,并且可以是任何上面的4个方向,而H2儿童可以是2个可能的方向中的任何一个 - 这需要证明)。
_._ _._
/ \ / \
(H4) . . (H4)
/ \ / \
. . . .
\ \
. .
很明显,第三次轮换要求受影响树的祖父母同样不平衡+/- 1,而第四轮要求大祖父母不平衡+/- 1,依此类推。
根据定义,子树的高度是每个分支的最大高度加上一个根的高度。一个兄弟必须比另一个兄弟高一个才能在根中达到+/- 1不平衡。
H(1) = 3 (as observed above)
H(k) = 1 + max(H(k - 1), H(k - 1) + 1)) = 1 + H(k - 1) + 1 = H(k - 1) + 2
... Inductive proof leading to H(k) = 2k + 1 eludes me.
最小节点
设N(h)=创建高度树h所需的最小节点数:
N(0) = 0
N(1) = 1
// the number of nodes in the two subtrees plus the root
N(h) = N(h-1) + N(h-2) + 1
从以下树中删除A并观察旋转后高度不会改变。因此,父母的平衡因子不会改变,也不会发生额外的轮换。
B B D
/ \ \ / \
A D => D => B E
/ \ / \ \
C E C E C
然而,在k = 2的情况下,如果H(4)在这里被最小化并不重要 - 第二次旋转仍然会发生。
_._ _._
/ \ / \
(H4) . . (H4)
/ \ / \
. . . .
\ \
. .