算法导论 练习12.3

12.3-1 给出TREE-INSERT过车过程的一个递归版本

//实现1
TREE-INSERT(T,z)
    if T.root = NIL //空树
        T.root = z
        z.p = NIL
    else    //非空,递归查找合适位置
        TREE-INSERT-RECURSIVE(T.root,z)

TREE-INSERT-RECURSIVE(x,z)
    if z.key < x.key
        if x.left = NIL
            x.left = z
            z.p = x
        else
            TREE-INSERT-RECURSIVE(x.left,z)
    else
        if x.right = NIL
            x.right = z
            z.p = x
        else
            TREE-INSERT-RECURSIVE(x.right,z)

//实现2
//调用 TREE-INSERT-CURSIVE(NIL,T.root,z)
//  y为父节点,x为插入位置
TREE-INSERT-CURSIVE(y,x,z)
    if x != NIL
        if z.key < x.key
            TREE-INSERT-CURSIVE(x,x.left,z)
            return
        else
            TREE-INSERT-CURSIVE(x,x.right,z)
            return
    z.p = y
    if y == NIL
        T.root = z
    else if z.key < y.key
        y.left = z
    else
        y.right = z


12.3-2 假设通过反复向一棵树中插入互不相同的关键字来构造一棵二叉搜索树。证明:在这棵树中查找关键字所检查过的结点数目等于先前插入这个关键字所检查的结点数目加1。

证明:根据书中TREE-INSERT的算法,我们插入一个结点,从根节点开始,判断合适位置插入。再次查找它时,我们沿着之前插入时判断的结点的路径(新插入的结点不会出现在该路径上,因此路径相同),最后再多检查结点本身,因此次数+1。


12.3-3 对于给定 n n n个关键字集合,可以通过先构造包含这些数据的一颗二叉搜索树(反复使用TREE-INSERT逐个插入这些数),然后按中序遍历输出这些数的方法,来对它们排序。这个排序算法的最坏情况运行时间和最好情况运行时间各是多少?

最坏情况下是BST的高度为 n n n,即按已经排序的方式插入。此时运行时间为 Θ ( n 2 ) \Theta(n^2) Θ(n2)。在最佳情况下,BST的形状是平衡的,意味着它的高度不超过 O ( l g n ) O(lgn) O(lgn)。此时运行时间为 O ( n l g n ) O(nlgn) O(nlgn),在题目12.1-5中已经说明最坏情况的需要 Ω ( n l g n ) \Omega(nlgn) Ω(nlgn)


12.3-4 删除操作可交换吗?可交换的含义是,先删除 x x x再删除 y y y留下的结果树与先删除 y y y再删除 x x x留下的结果树完全一样。如果是,说明为什么?否则,给出一个反例。

不可以交换,反例如下:

在这里插入图片描述
先删除1,再删除2,不同于先删除2,再删除1


12.3-5 假设为每个结点换一种设计,属性 x . p x.p x.p指向父亲,属性 x . s u c c x.succ x.succ指向 x x x的后继。给出使用这种表示法的二叉搜索树 T T T上SEARCH、INSERT和DELETE操作的伪代码。这些伪代码再 O ( h ) O(h) O(h)时间内执行完,其中 h h h T T T的高度。(提示:应该设计一个返回某个结点的双亲的子过程)。

未解决。有好的想法的可以私我。


12.3-6 当TREE-DELETE中的结点 z z z有两个孩子时,应该选择结点 y y y作为它的前驱,而不是作为它的后继。如果这样做,对TREE-DELETE应该做哪些什么必要的修改?一些人提出了一个公平的策略,为前驱和后继赋予相等的优先级,这样得到了较好的实验性能。如何对TREE-DELETE进行修改来实现这样一种公平策略?

第一个问题:如果转换成删除前驱,只需要在TREE-DELETE中将有两个孩子的情况修改。

下面是我的伪代码实现

TREE-DELETE(T,z)
    if z.left == NIL
        TRANSPLANT(T,z,z.right)
    else if z.right == NIL
        TRANSPLANT(T,z,z.left)
    else y = TREE-MAXIMUM(z.left)
        if y.p != z
            TRANSPLANT(T,y,y.left)
            y.left = z.left
            y.left.p = y
        TREESPLANT(T,z,y)
        y.right = z.right
        y.right.p = y

第二个问题:要实现前驱后继相等的优先级,当有两个孩子时,可以采用一个随机数来决定采用前驱替换还是后继替换。

TREE-DELETE(T,z)
    if z.left == NIL
        TRANSPLANT(T,z,z.right)
    else if z.right == NIL
        TRANSPLANT(T,z,z.left)
    else
        LorR = getRandomBool
        if LorR == true
            。。。//替换后继
        else
            。。。//替换前驱
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值