繁体   English   中英

在 Python 中迭代删除二叉搜索树中的值

[英]Deleting a value in a Binary Search Tree iteratively in Python

我目前正在学习一门学习数据结构和算法的课程,我正在学习 BST。 我已经让代码可以工作并理解其中的大部分内容,但是我有一个关于删除功能的问题。 这是我的代码的样子:

class BST:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

    def insert(self, value):
        currentNode = self

        while True:
            if value < currentNode.value:
                if currentNode.left is None:
                    currentNode.left = BST(value)
                    break
                else:
                    currentNode = currentNode.left
            else:
                if currentNode.right is None:
                    currentNode.right = BST(value)
                    break
                else:
                    currentNode = currentNode.right
        return self

    def contains(self, value):
        currentNode = self

        while currentNode is not None:
            if value < currentNode.value:
                currentNode = currentNode.left
            elif value > currentNode.value:
                currentNode = currentNode.right
            else:
                return True
        return False

    def remove(self, value, parentNode = None):
        currentNode = self

        while currentNode is not None:
            if value < currentNode.value:
                parentNode = currentNode
                currentNode = currentNode.left  
            elif value > currentNode.value:
                parentNode = currentNode
                currentNode = currentNode.right
            #Found the node
            else:   
            #two child ondes
                if currentNode.left is not None and currentNode.right is not None:
                    currentNode.value = currentNode.right.getMinValue()      #get the left number from the right subtree
                    currentNode.right.remove(currentNode.value, currentNode) #remove that most left number by using remove() 
                                                                             #on the right currentNode
                #root node
                elif parentNode is None:
                    if currentNode.left is not None:
                        currentNode.value = currentNode.left.value
                        currentNode.right = currentNode.left.right
                        currentNode.left = currentNode.left.left
                    elif currentNode.right is not None:
                        currentNode.value = currentNode.right.value
                        currentNode.left = currentNode.right.left
                        currentNode.right = currentNode.right.right
                    #only 1 item left in BST
                    else:
                        pass
                #one child node
                elif parentNode.left == currentNode:
                    parentNode.left = currentNode.left if currentNode.left is not None else currentNode.right
                elif parentNode.right == currentNode:
                    parentNode.right = currentNode.left if currentNode.left is not None else currentNode.right
                break
        return self

    def getMinValue(self):
        currentNode = self

        while currentNode.left is not None:
            currentNode = currentNode.left
        return currentNode.value

我明白,对于删除功能:

  1. while循环将遍历每个节点并运行直到没有更多节点
  2. 第一个ifelif用于查找您要删除的节点。
  3. else适用于实际删除,它有 3 个不同的选项: currentNode有两个子节点,您只需将其替换为右侧节点的最左侧值,然后从右侧 noe 中删除最左侧的值。 另一种情况是parentNode没有父节点,这将是根节点的情况。 最后一种情况是当您只有一个子节点时,您所要做的就是将currentNode的值更改为其左节点或右节点(取决于它具有哪个节点)。

我不太清楚的是条件背后的逻辑,以及当我们想要删除root时它是如何工作的。 代码不应该也运行第一个条件,即两个子节点的条件吗? 我几乎可以肯定这不应该发生,并且条件应该只针对其特殊情况运行。 我一遍又一遍地看过视频解释,但我就是不明白。

当我们要删除根节点时。 代码不应该也运行第一个条件,即两个子节点的条件吗?

即使在情况下,根节点必须拆除,实际评估的首要条件。 如果根节点同时具有左子节点和右子节点,则“选项 1”适用于它:第一个选项可以很好地处理任何具有两个子节点的节点,无论它是否是根节点。 在此选项中不需要区分根节点或非根节点。

其他两个选项仅适用于没有两个孩子的节点。 您似乎建议(也在代码注释中)只有选项 3 处理这种情况,但选项 2 也可以。 选项2是当节点节点育有两个孩子这是根本。 如果根有 2 个孩子,它将被视为选项 1。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM