Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于bst删除节点时的两个疑问 #9

Closed
hjlarry opened this issue Jun 9, 2018 · 3 comments
Closed

关于bst删除节点时的两个疑问 #9

hjlarry opened this issue Jun 9, 2018 · 3 comments

Comments

@hjlarry
Copy link
Contributor

hjlarry commented Jun 9, 2018

请教两个问题,谢谢

一、 “删除只有一个孩子的节点时,只要把它的父亲指向它的孩子”,这里貌似有问题,例如:
root的key为60,左孩子为10,右孩子为70,然后70的左孩子为30
若删除70这个节点,则按上述规则30将会成为60的右孩子,不符合bst特性

二、 删除两个孩子的节点时,代码是这么写的:
successor_node = self._bst_min_node(subtree.right)
subtree.key, subtree.value = successor_node.key, successor_node.value
subtree.right = self._bst_remove(subtree.right, successor_node.key)

既然是互换了两个节点,为什么要最后一行给互换后节点的右孩子再去赋值?是否直接self._bst_remove(subtree.right, successor_node.key)就可以了?

@PegasusWang
Copy link
Owner

PegasusWang commented Jun 10, 2018

  1. 第一个问题,插入的时候 30 是不会成为 70 的左孩子的,按照 bst 的插入特性,30 只会插入到 root 的左子树,因为比 root 的 60 要小,所以这个前提不会成立。

  2. 删除两个孩子的内部节点有三个步骤:

  • 找到待删除节点 N 的后继节点 S
  • 复制节点 S 到节点 N
  • 从 N 的右子树中删除节点 S,并更新其删除后继节点后的右子树
    这里赋值的意思是表明把当前子树的右子树更新为删除后继节点后的子树,假如右子树此时为 None 了,不更新的话依然指向老的右子树节点,而此时右子树应该是 None。

你可以给 Bst 加上个中序遍历的方法:

   def inorder_trav(self, subtree):
       if subtree is not None:
           self.inorder_trav(subtree.left)
           print(subtree.key)
           self.inorder_trav(subtree.right)

然后直接测试:

def test_bst_tree():
    bst = BST.build_from(NODE_LIST)
    for node_dict in NODE_LIST:
        key = node_dict['key']
        assert bst.get(key) == key
    assert bst.size == len(NODE_LIST)
    assert bst.get(-1) is None    # 单例的 None 我们用 is 来比较

    assert bst.bst_min() == 1
    bst.remove(29) # 直接删除一个包含两个孩子的内部节点
    print('\n')
    bst.inorder_trav(bst.root)
    print('\n')

你会看到赋值和不赋值之间的差别。
最后,交换的地方确实有个手误,感谢及时发现,已经合并。不知道有没有表述清楚呢?

@hjlarry
Copy link
Contributor Author

hjlarry commented Jun 11, 2018

感谢大佬 两个问题都已想明白了

@PegasusWang
Copy link
Owner

好,如果解答了你的疑问这个 issue 我就 close 了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants