简体   繁体   English

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

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

I'm currently taking a course where I'm learning data structures and algorithms, and I'm learning about BST's.我目前正在学习一门学习数据结构和算法的课程,我正在学习 BST。 I already got the code to work and understand most of it, but I got a question for the deletion function.我已经让代码可以工作并理解其中的大部分内容,但是我有一个关于删除功能的问题。 This is what my code looks like:这是我的代码的样子:

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

I understand that, for the delete function:我明白,对于删除功能:

  1. The while loop will iterate over each node and run until there are no more nodes while循环将遍历每个节点并运行直到没有更多节点
  2. The first if and elif are used to find the node you are trying to remove.第一个ifelif用于查找您要删除的节点。
  3. The else works for the actual deletion, which has 3 differnt options: Either currentNode has two childs, and you just replace it by the leftmost value of the right node and delete this leftmost value from the right noe. else适用于实际删除,它有 3 个不同的选项: currentNode有两个子节点,您只需将其替换为右侧节点的最左侧值,然后从右侧 noe 中删除最左侧的值。 The other case is that parentNode has no parent, which would be the root Node case.另一种情况是parentNode没有父节点,这将是根节点的情况。 And the last case is when you have only one child node all you have to do is change the value of currentNode either to its left node or right node (depending which one it has).最后一种情况是当您只有一个子节点时,您所要做的就是将currentNode的值更改为其左节点或右节点(取决于它具有哪个节点)。

What I don't clearly understand is the logic behind the conditions, and how it works when we want to delete a root node.我不太清楚的是条件背后的逻辑,以及当我们想要删除root时它是如何工作的。 Isn't the code supposed to also run the first condition, which is the one for two child nodes?代码不应该也运行第一个条件,即两个子节点的条件吗? I'm almost certain that this isn't supposed to happen, and the condition should only run for its special case.我几乎可以肯定这不应该发生,并且条件应该只针对其特殊情况运行。 I have seen again and again the video explanation, but I just can't get a hang of it.我一遍又一遍地看过视频解释,但我就是不明白。

when we want to delete a root node.当我们要删除根节点时。 Isn't the code supposed to also run the first condition, which is the one for two child nodes?代码不应该也运行第一个条件,即两个子节点的条件吗?

Even in case the root node must be removed, it actually does evaluate the first condition.即使在情况下,根节点必须拆除,实际评估的首要条件。 If the root node has both a left and right child, then "option 1" applies to it: that first option deals fine with any node that has two children, whether it be a root node or not.如果根节点同时具有左子节点和右子节点,则“选项 1”适用于它:第一个选项可以很好地处理任何具有两个子节点的节点,无论它是否是根节点。 No distinction needs to be made between a root or non-root node in this option.在此选项中不需要区分根节点或非根节点。

The other two options are only for nodes that do not have two children.其他两个选项仅适用于没有两个孩子的节点。 You seem to suggest (also in the code comments) that only option 3 deals with that case, but also option 2 does.您似乎建议(也在代码注释中)只有选项 3 处理这种情况,但选项 2 也可以。 Option 2 is for when the node node does not have two children and it is the root.选项2是当节点节点育有两个孩子这是根本。 If the root would have had 2 children, it would be treated as option 1.如果根有 2 个孩子,它将被视为选项 1。

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

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