【发布时间】:2022-11-16 05:49:02
【问题描述】:
我有 2 个函数可以从二叉搜索树中删除节点。第一个是删除树的根,第二个是删除树中的任何其他节点。
问题是在第 3 次迭代后进行测试时,事情开始变得不稳定。 DEL: 45 行删除节点 45、30、20,而 DEL: 40 行不删除 40 但删除 40 之后的所有内容并重复重新附加 30、20、45。
我感觉 while 循环出了点问题,不管是什么问题,都在进入下一组循环并破坏树。
预期结果应该只删除描述的值,并使树结构尽可能接近原来的样子。我在重新连接现有节点时做错了什么? 我调试的时候发现
if node.right is None and node.left is None:
pn.right = None
pn.left = None
是什么从 DEL 45 行中删除节点 20 和 30
def remove_start_node(self) -> bool:
"""
deletes the root note of the BST. first checks if the BST is empty and if there
is only the root exists. If empty, return False. If only the root exists, delete the root node.
else, find the in order successor of the root node(leftmost child of the right subtree.)
if the deleted node only has a left subtree,the left node becomes the rood node of the subtree.
"""
if self._root is None:
return False
if self._root.left is None and self._root.right is None:
self._root = None
elif self._root.right is None: # checks if only left subtree exists
self._root = self._root.left
else:
subtree = self._root.right
par_tree = subtree
while subtree.left is not None: # traverse down till the in order successor is found (leftmost child)
par_tree = subtree
subtree = subtree.left
if subtree != self._root.right: # reestablish structure
par_tree.left = subtree.right
subtree.right = self._root.right
subtree.left = self._root.left
self._root = subtree
return True
def remove(self, value) -> bool:
"""
first traverses throughout the BST and deletes the target value while restructuring the BST.
# first checks if BST is empty, if there is only one node, and if the value is contained within the BST.
# if empty, return False. if only node, delete the root node. else, find the in order successor of the current
# node which is the leftmost child of the right subtree of the current node. If the deleted node only has the
# left subtree, the current node becomes the rood node of the left subtree.
"""
if not self.contains(value): # check if the value exists
return False
if self._root is None: # checks if BST is empty
return False
if self._root.value == value: # checks if the value matches the root node
self.remove_start_node()
return True
# traverse through the tree first until the value is found
x = self._root
pn = None
while x is not None: # traverse through the tree
if x.value == value:
node = x
break
elif value < x.value:
pn = x
x = x.left
else:
pn = x
x = x.right
# if successor has no children, parent node's children is updated to None
if node.right is None and node.left is None:
pn.right = None
pn.left = None
elif node.right is None: # if successor only has a left child, point parent to its children
pn.right = node.left
else: # once successor is found, traverse to the left most child
subtree = node.right
par_tree = subtree
while subtree.left is not None:
par_tree = subtree
subtree = subtree.left
if subtree != node.right: # reestablish structure
par_tree.left = subtree.right
subtree.right = node.right
pn.right = subtree # point parent to new subtree
temp = node.left # store any other subtrees from the deleted node
node = subtree # replace successor with current node
node.left = temp # reattach remaining subtrees
return True
-------------------------------
INPUT : BST pre-order { 1, 2, 3 } DEL: 1
RESULT : BST pre-order { 2, 3 }
INPUT : BST pre-order { 1, 2, 3 } DEL: 2
RESULT : BST pre-order { 1, 3 }
INPUT : BST pre-order { 1, 2, 3 } DEL: 3
RESULT : BST pre-order { 1, 2 }
INPUT : BST pre-order { 50, 40, 30, 20, 45, 60, 70, 80 } DEL: 0
RESULT : BST pre-order { 50, 40, 30, 20, 45, 60, 70, 80 }
**INPUT : BST pre-order { 50, 40, 30, 20, 45, 60, 70, 80 } DEL: 45
RESULT : BST pre-order { 50, 40, 60, 70, 80 }
INPUT : BST pre-order { 50, 40, 30, 20, 45, 60, 70, 80 } DEL: 40
RESULT : BST pre-order { 50, 40, 30, 20, 45, 30, 20, 45, 30, 20 }**
INPUT : BST pre-order { 50, 40, 30, 20, 45, 60, 70, 80 } DEL: 30
RESULT : BST pre-order { 50, 40, 30, 20, 20, 60, 70, 80 }
【问题讨论】:
-
根节点并没有什么特别之处。有趣的情况是一棵空树(什么都不做),一个没有孩子的节点(删除节点),一个只有一个孩子的节点(用那个孩子替换节点)和一个有两个孩子的节点。最后一种情况比较棘手,因为它涉及选择两个孩子中的一个来替换节点,并将另一个孩子移植到以所选节点为根的子树中。
标签: python data-structures binary-search-tree