【问题标题】:Remove recursively from a BST从 BST 中递归删除
【发布时间】:2019-03-23 01:36:22
【问题描述】:

当我要删除的节点是根节点或叶节点时,我已经完成了这种情况,但是当它有兄弟姐妹或孩子时,我也需要能够删除,我发现这很难。

class Node:
    def __init__(self, key=None, data=None):
        self.key = key
        self.data = data
        self.left = None
        self.right = None


class BST:
    def __init__(self):
        self.root = None
        self.size = 0

    def remove(self, key):
        self.root = self._remove(key, self.root)

    def insert(self, key, data):
        self.root = self._insert(self.root, key, data)

    def _insert(self, root, key, data):
        if root == None:
            self.size += 1
            return Node(key, data)
        if root.key == key:
            return root
        elif root.key > key:
            root.left = self._insert(root.left, key, data)
        else:
            root.right = self._insert(root.right, key, data)
        return root

    def _remove(self, key, node):
        if node == None:
            return None
        if key == node.key:
            if node.left != None and node.right == None:  # if trying to remove root and right side is empty
                return node.left
            elif node.left == None and node.right != None:  # if trying to remove root and left side is empty
                return node.right
            elif node.left == None and node.right == None:  # if trying to remove leaf
                return node
            # two more cases to check when it has siblings

        # iterates recursively in the bst
        elif key <= node.key:
            node.left = self._remove(key, node.left)
        else:
            node.right = self._remove(key, node.right)

        return node

我发布了整个代码,所以如果有人想在他们的机器上进行测试,欢迎这样做,或者有人可以将它用于教育目的。

【问题讨论】:

    标签: python recursion binary-search-tree


    【解决方案1】:

    将来尝试执行一些调试并提供一些示例输出和预期输出。

    考虑下面

    def _remove(self, key, node):
            if node == None:
                return None
            if key == node.key:
                if node.left and not node.right:  # only left
                    return node.left
                elif node.right and not node.left: # only right
                    return node.right
                elif not node.right and not node.left: # neither
                    return None
                else : # both
                    inorder_successor = node.right
                    while inorder_successor.left:
                        inorder_successor = inorder_successor.left
                    # remember to replace inorder_successor with it's right child
                    ...
                    ...
                    return inorder_successor
    
            # iterates recursively in the bst
            elif key <= node.key:
                node.left = self._remove(key, node.left)
            else:
                node.right = self._remove(key, node.right)
    
            return node
    

    关于变化的一些观察

    1. 您使用is != None 检查None,这是一种非常非Pythonic 的方式。只需检查 isis not 即可
    2. 在具有两个子节点的 BST 中替换节点的正确方法是使用中序后继节点(已删除节点的右子节点的最左边的后代)

    【讨论】:

    • 感谢您的观察和帮助,我刚刚完成了我的自我,当它有两个孩子时,我没有发布输入和输出,因为我认为那些理解这一点的人不需要任何输入,但是,是的,有输入和预期输出总是好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多