在Python中迭代删除二进制搜索树中的值
我目前正在学习一门课程,学习数据结构和算法,学习BST。我已经得到了工作的代码,并理解了其中的大部分内容,但我有一个关于删除函数的问题。这就是我的代码的样子:在Python中迭代删除二进制搜索树中的值,python,algorithm,data-structures,iteration,binary-search-tree,Python,Algorithm,Data Structures,Iteration,Binary Search Tree,我目前正在学习一门课程,学习数据结构和算法,学习BST。我已经得到了工作的代码,并理解了其中的大部分内容,但我有一个关于删除函数的问题。这就是我的代码的样子: class BST: def __init__(self, value): self.value = value self.left = None self.right = None def insert(self, value): currentNode
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
BST级:
定义初始值(自身,值):
自我价值=价值
self.left=无
self.right=无
def插入(自身,值):
currentNode=self
尽管如此:
如果值currentNode.value:
currentNode=currentNode.right
其他:
返回真值
返回错误
def remove(self、value、parentNode=None):
currentNode=self
当currentNode不是None时:
如果值currentNode.value:
parentNode=currentNode
currentNode=currentNode.right
#找到了节点
其他:
#两个孩子
如果currentNode.left不是None,currentNode.right不是None:
currentNode.value=currentNode.right.getMinValue()#从右子树中获取左数
currentNode.right.remove(currentNode.value,currentNode)#使用remove()删除最左边的数字
#在右侧的currentNode上
#根节点
elif parentNode为无:
如果currentNode.left不是无:
currentNode.value=currentNode.left.value
currentNode.right=currentNode.left.right
currentNode.left=currentNode.left.left
elif currentNode.right不是无:
currentNode.value=currentNode.right.value
currentNode.left=currentNode.right.left
currentNode.right=currentNode.right.right
#BST中只剩下1项
其他:
通过
#单子节点
elif parentNode.left==当前节点:
parentNode.left=currentNode.left,如果currentNode.left不是None-else currentNode.right
elif parentNode.right==当前节点:
如果currentNode.left不是其他任何currentNode.right,则parentNode.right=currentNode.left
打破
回归自我
def getMinValue(自身):
currentNode=self
currentNode.left不是无:
currentNode=currentNode.left
返回currentNode.value
我理解,对于删除功能:
while
循环将在每个节点上迭代并运行,直到没有更多节点为止if
和elif
用于查找要删除的节点else
用于实际删除,它有3个不同的选项:要么currentNode
有两个子节点,您只需将其替换为右节点最左边的值,然后从右noe中删除该最左边的值。另一种情况是parentNode
没有父节点,这就是根节点的情况。最后一种情况是,当您只有一个子节点时,您所要做的就是将currentNode
的值更改为其左节点或右节点(取决于它有哪个节点)根节点时它是如何工作的。代码是否也应该运行第一个条件,即两个子节点的条件?我几乎可以肯定,这是不应该发生的,这种情况应该只适用于它的特殊情况。我看了一遍又一遍的视频解说,但我就是搞不懂
当我们想要删除根节点时。代码是否也应该运行第一个条件,即两个子节点的条件
即使在必须删除根节点的情况下,它实际上也会计算第一个条件。如果根节点同时具有左和右子节点,则“选项1”适用于它:第一个选项适用于具有两个子节点的任何节点,无论它是否为根节点。在该选项中,不需要区分根节点和非根节点
其他两个选项仅适用于没有两个子节点的节点。您似乎建议(也在代码注释中)只有选项3处理这种情况,但选项2也处理这种情况。选项2用于当节点没有两个子节点且它是根节点时。如果根有两个孩子,它将被视为选项1。我建议在注释#两个子ondes
中添加缩进级别,并将注释#根节点
替换为#根节点,最多有一个子节点
。这看起来还像是尝试从树中删除一个没有子节点的节点时,会自动失败,由于elif parentNode下的else:pass
为None:
。无声错误通常应为b