尝试在python中构建二进制搜索树,并遇到了这个奇怪的错误。使用我的delete_node函数删除节点后,仍然会打印已删除的节点,但只有正确删除的节点是连接了两个其他节点的节点(这些节点应该是最难删除的) 这是代码:
class Node:
def __init__(self, data):
self.Left = self.Right = None
self.T_data = data
# function that deletes nodes from the tree
def delete_node(self, item):
if self is None:
return self
elif item < self.T_data:
self.Left.delete_node(item)
elif item > self.T_data:
self.Right.delete_node(item)
else:
# case when the node we want to delete has no leaves attached to it
if self.Right is None and self.Left is None:
self = None
# cases when a node has either left or right leaf node
elif self.Left is None:
temp = self.Right
self = None
return temp
elif self.Right is None:
temp = self.Left
self = None
return temp
else: #case when a node has two leaf nodes attached
temp = self.Right.min_node()
self.T_data = temp.T_data
self.Right = self.Right.delete_node(temp.T_data)
return self
正如您所看到的,删除节点的方式是使用递归,因此要使双分支节点删除,单分支节点删除应该正常工作,但事实并非如此。
继承了打印功能以及如何调用函数:
# function that prints contents of the tree in preorder fashion
def print_tree_preorder(self):
if self is None:
return
print("%s" % self.T_data)
if self.Left is not None:
self.Left.print_tree_preorder()
if self.Right is not None:
self.Right.print_tree_preorder()
x = int(input("Which element would you like to delete?\n"))
root = root.delete_node(x)
root.print_tree_preorder()
答案 0 :(得分:0)
你现在在做什么,当你有:
self = None
不实际上是删除对象本身。您正在做的是将self
分配给不同的值。
我认为说明这个问题的好方法是将self
和其他变量视为标记。
当你说:
a = 3
你基本上把标记a
放在实体3上.3驻留在内存中的某个地方,a
“指向”3(尽管C ++中的指针实际上不是python中的引用,如果要进行比较,请小心。
当您将self
指向None
时,您想要的内容是:
所以我想删除这个对象,指向此对象的所有内容都将指向
None
。
但是,您现在所说的是:
所以我想将
self
标记设置为指向None
。
哪个完全不同。仅仅因为您将self
代码设置为None
并不意味着您也将节点的父级.Right
或.Left
成员设置为None
。
解决方案?嗯,你不会喜欢这个,但是你必须要么:
指向每个节点的父节点,并将父节点的子节点(具体为此子节点)设置为None
。
检查树中更深层的1个级别,这样就可以删除子节点而不是删除节点本身。
2节点子节点的工作原理是因为您在此处设置了对象的属性,而不是设置self=None
。这意味着你仍然指向同一个对象,特别是在这一行:
self.T_data = temp.T_data
这是之间的区别“着色一个对象不会使它成为一个不同的对象。它的特征只是不同”与“用另一个对象替换一个对象使它成为一个不同的对象”