算法导论14.2如何扩张数据结构 练习总结

14.2-1 通过为结点增加指针的方式,试说明如何在扩张的顺序统计树上,支持每一动态集合查询操作 MINIMUM、MAXIMUM、SUCCESSOR 和 PREDECESSOR 在最坏时间 O(1) 内完成。顺序统计树上的其他操作的渐进性能不受影响。

ANSWER:

① MINIMUM:用一个指针指向树中最小的元素。每次插入时与 MINIMUM 比较检测是否需要更改。若删除 MINIMUM,则指针指向它的后继。旋转不影响 MINIMUM。

② MAXIMUM:同 MINIMUM。

③ PREDECESSOR、SUCCESSOR:给每个结点新增指向前驱和指向后继的指针。

插入:时间复杂度仍为 O(lgn)

插入 x 结点时,若 x ≠ MAXIMUM,利用 O(lgn) 时间找到 x 的后继 y,找到 y 后,y 的前驱 w 则只需 O(1) 时间,在用 O(1) 时间更新 w, x, y 的前驱、后继。若x == MAXIMUM,则利用 O(lgn) 时间找 x 的前驱,同理。

删除:和插入类似。

旋转不影响前驱、后继的指针。


14.2-2 能否在不影响红黑树任何操作的渐进性能的前提下,将结点的黑高作为书中结点的一个性能来维护?说明如何做,如果不能,请说明理由。如何维护结点的深度?

ANSWER:可以,插入和删除操作支队根结点刀某一叶结点上的路径上的结点(或部分叔结点)进行修改,即 O(lgn) 个结点。

而自插入(删除)结点向上,每个结点黑高修改只需 O(1) 时间。根据插入和删除的不同情况进行修改操作即可。所以总的修改时间为 O(lgn)。


*14.2-3 设 ⊙ 为一个满足结合律的二元运算符,a 为红黑树中每个结点上的一个要维护的属性,假设在每个结点 x 上增加一个属性 f,使 x.f = x1.a ⊙ x2.a ⊙...⊙ xm.a,其中 x1, x2,...,xm 是以 x 为根的子树中按中序次序排列的所有结点。说明在一次旋转后,如何在 O(1) 时间内更新 f 属性。对你的扩张稍做修改,使得它能够应用到顺序统计树的 size 属性中。

ANSWER:旋转只对 O(1) 个结点修改,旋转后只需对旋转了的 O(1) 个结点进行 x.f = x.left.f ⊙ x.a ⊙ x.right.f 修改即可。所以总时间为 O(1)。

*14.2-4 希望设计一个操作 RB-ENUMERATE(x, a, b),来对红黑树进行扩张。该操作输出所有的关键字 k,使得在以 x 为根的红黑树中有 a ≤ k ≤ b。描述如何在 Θ(m+lgn) 时间内实现 RB-ENUMERATE,其中 m 为输出的关键字数目,n 为树种的内部结点数。(提示:不需要向红黑树中增加新的属性。)

ANSWER:在红黑树中查找关键字 a;若不存在,则插入关键字 a,再查找 a 的后继;删除结点 a。然后调用 m 次后继函数,直至发现下一个后继的关键字大于 b。PS:连续 m 次调用后继函数的时间为 O(m+h),即O(m+lgn)。证明见 12.2-8 。

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