算法导论13.2旋转 练习总结

13.2-1 写出RIGHT-ROTATE 的伪代码。

ANSWER:

伪代码:
RIGHT_ROTATA:
    y = x.left
    x.left = y.right
    if y.right ≠ T.nil:
        y.right.p = x
    y.p = x.p
    if y.p == T.nil:
        T.root = y
    else if x = x.p.left:
        y = x.p.left
    else:
        y = x.p.right
    y.right = x
    x.p = y

13.2-2 证明:在任何一棵有 n 个结点的二叉搜索树中,恰有 n-1 种可能的旋转。

ANSWER:

① 当n = 1 时,a(n) = 0 = 1 - 1,a(n) = a(i) + a(n-i-1) + 2,用数学归纳法容易证明 a(n) = n - 1.
② 当有 n 个结点时,共有 n - 1 对父子结点对,每一对父子结点对可形成一个旋转,所以有 n-1 中可能的旋转。

13.2-3 设在图 13-2 左边一棵树中,a、b 和 c 分别为子树 α、β 和 γ 中的任意结点。当结点 x 左旋之后,a、b 和 c 的深度会如何变化?
ANSWER:
deep(a) = deep(a) + 1;
deep(b) = deep(b);
deep(c) = deep(c) - 1。

13.2-4 证明:任何一棵含 n 个结点的二叉搜索树可以通过 O( n ) 次旋转,转变为其他任何一棵含 n 个结点的二叉搜索树。(提示:先证明至多 n-1 次右旋足以将树转变为一条右侧伸展的链。)
ANSWER:
证明:按照中序遍历的顺序,从根结点开始右旋,直至左子树为空;然后对右子树进行上述操作,直至二叉树变成升序排列的链。而没进行一次上述的右旋操作,都会将一个不在这样的链上的结点旋转到这样的链上,所以该操作的步数为 O(n)。
每一棵 n 个结点的二叉搜索树都能通过这样的 O(n) 的步数旋转成右侧伸展的链,再按照相应的逆操作即可通过 O(n) 次旋转变成任意的 n 个结点的二叉搜索树。
算法导论13.2旋转 练习总结_第1张图片

13.2-5 如果能够使用一些列的 RIGHT-ROTATE 调用把一个二叉搜索树 T1 变为二叉搜索树 T2,则称 T1 可以右转成 T2。试给出一个例子表示两棵树 T1 和 T2,其中 T1 不能够右转成 T2。然后,证明:如果 T1 可以右转成 T2,那么它可以通过 O(n^2) 次 RIGHT-ROTATE 调用来实现右转。
ANSWER:
不能右转示例:
算法导论13.2旋转 练习总结_第2张图片
假设 T1 可以右转成 T2,若 T1.root ≠ T2.root,则可以对 T1 进行 O(n) 次右旋变换成 T1.root = T2.root,然后对 T1 的左右子树分别进行递归调用。T(n) = T(i) + T(n-i-1) + O(n),利用代入法或画出递归树易得 T(n) = O(n^2)。

你可能感兴趣的:(算法,算法导论)