算法导论13.2 Exercises 答案
13.2-1
算法的伪代码由RIGHT-ROTATE给出,其和LEFT-ROTATE非常类似。
1 | RIGHT-ROTATE(T, y) |
13.2-2
对于任意一个节点$x$,如果它有右子节点$r$,那么可以进行左旋,从而将$r$旋转到$x$的位置;如果它有左子节点$l$,那么可以进行右旋,将$l$旋转到$x$的位置。
可见,如果当前节点$x$能够进行旋转,关键在于看它是否包含左/右子节点。只要包含一个子节点就能进行一次旋转。如果$x$拥有一个子节点,那么$x$恰好就需要一条边连接着它,这恰好对应了某一个旋转方案。
由于$T$中一共有$n-1$条边,因此$T$中有$n-1$种不同的旋转方式。
13.2-3
由图可以得知,$a$的深度增加了$1$;$b$的深度保持不变;$c$的深度减少了$1$。
13.2-4
对于任意一棵树$T$,考虑按照如下策略将其旋转成一条向右伸展的链$R$:从根节点出发,一直访问右子节点,直到最右侧的节点,得到一条路径$P=(v_1,v_2,\dots,v_m)$。如果这条路径上存在一个节点$x$,其左子节点非空,那么对$x$进行一次右旋,那么路径$P$将会增加一个节点。
当路径$P$包含了全部节点时,上述右旋过程结束。由于进行一次右旋操作,$P$就会增加一个节点,并且$T$中最多只有$n$个节点,因此最多$n-1$次右旋操作就可以将$T$旋转成$R$。
此外,由于右旋的操作是可逆的(对应一次左旋),因此从$R$旋转成任意一棵树同样至多只需要$n-1$次左旋操作。
那么,假设现在需要从$T$通过旋转操作变成$T’$,那么从$T$变换到$R$需要$c_1$次操作,从$R$变换到$T’$需要$c_2$次操作。那么总操作次数$c$满足$c\le c_1+c_2\le 2n-2$。因此$c=O(n)$,原结论成立。
$\star$ 13.2-5
如下如所示,左边的$T_1$无法通过右旋操作转化为$T_2$。
graph TD 1((1)) 2((2)) 3(( )) 4((1)) 5((2)) 6(( )) style 3 fill:#f100,stroke-width:0px style 6 fill:#f100,stroke-width:0px 1---3 1---2 5---4 5---6 linkStyle 0 stroke:#0ff,stroke-width:0px linkStyle 3 stroke:#0ff,stroke-width:0px
如果$T_1$能够只通过右旋操作转换成$T_2$,那么考虑进行递归操作。$T_2$的根节点必定在$T_1$中最左的路径上(即从根节点出发,一直访问左子节点,直到最左侧的叶节点,得到一条路径$P=(v_1,v_2,\dots,v_m)$)。因此,使用$O(n)$次的操作可以将这个根节点旋转到根的位置。那么接下来对这棵树的子树递归进行这种旋转操作。由于这棵树一共有$n$个节点,因此所需要的操作次数最多为$n\cdot O(n)=O(n^2)$。