我正在尝试实现二叉搜索树,但是我认为我犯了逻辑和语法错误,现在放屁了。
我按照我拥有的伪代码实现了基本操作(我无法重构代码)。到目前为止,我实现的是class find,findMax,Insert,Traverse,但是看起来我在某个地方犯了逻辑错误,有帮助吗?
#!/usr/bin/python3.6
class Node:
def __init__(self, key=None):
self.key = key
self.left = None
self.right = None
class BST:
root = Node()
def find0(self, key):
x = self.find(self.root, key)
return x
# Recusive
def find(self, root, key):
if root is None or key == self.root.key:
return self.root
elif key > self.root.key:
return self.find(self.root.right, key)
else:
return self.find(self.root.left, key)
def findMin0():
FNode = self.findMin(self.root)
return FNode
# Recursive
def findMin(self, root):
if self.root.right is None:
return self.root
else:
return findMin(self.root.left)
def findMax0():
FNode = findMin(self.root)
return FNode
# Recursive
def findMax(self, root):
if self.root.right is None:
return self.root
else:
return findMin(self.root.left)
def insert(self, data):
self.root = self.insertInTree(self.root, data)
def insertInTree(self, root, key):
if root.left is None and root.right is None :
root = Node(key)
return root
elif key < root.key:
root.left = self.insertInTree(root.left, key)
elif key > root.key:
root.right = self.insertInTree(root.right, key)
return root
def traverseInOrder0(self):
self.traverseInOrder(self.root)
def traverseInOrder(self, root):
if root.key is not None:
self.traverseInOrder(root.left)
self.visit(root)
self.traverseInOrder(root.right)
def visit(self, node):
print (node.key)
def getRoot():
return root
def main():
NewTree = BST()
NewTree.insert(100)
NewTree.insert(90)
NewTree.insert(110)
NewTree.traverseInOrder0()
#NewTree.findMin()
if __name__ == "__main__":
main()
截至目前,我可以看到以下错误
Traceback (most recent call last):
File "./bst", line 86, in <module>
main()
File "./bst", line 81, in main
NewTree.traverseInOrder0()
File "./bst", line 61, in traverseInOrder0
self.traverseInOrder(self.root)
File "./bst", line 65, in traverseInOrder
self.traverseInOrder(root.left)
File "./bst", line 64, in traverseInOrder
if root.key is not None:
AttributeError: 'NoneType' object has no attribute 'key'
答案 0 :(得分:3)
有几个问题。
此插入函数将始终替换根,而从不实际插入任何新内容:
def insertInTree(self, root, key): if root.left is None and root.right is None : root = Node(key) return root ...
因为一开始,root没有子代,所以采用了这种if
条件,
用新节点替换root。
由于新节点没有子节点,
当您再次调用此函数以插入另一个值时,
它将再次发现根没有子,
然后替换root。它总是只替换root,
它永远不会插入任何新内容。
另一个问题是遍历:
def traverseInOrder(self, root): if root.key is not None: self.traverseInOrder(root.left) self.visit(root) self.traverseInOrder(root.right)
key
何时None
?应该永远不会。节点应始终具有密钥。
另一方面,left
和right
子级可以是None
。
递归调用导致您的问题中出现异常。
例如,当root.left
为None
时,
对self.traverseInOrder(root.left)
的调用将导致评估if root.key is ...
,
但是root
是None
,导致您的问题中出现例外情况。
可能还有其他问题, 在这一点上,我停止阅读。 我建议更深入地研究伪代码。
答案 1 :(得分:1)
如果设置了traverseInOrder
,则root.left
方法无条件地下降到root.right
和root.key
中。如果其中任何一个缺少key
成员(例如,因为他们是None
),那么您将失败。为了避免这种情况,如果traverseInOrder
是root
,None
应该在最顶端终止,或者如果不是None
,则只能降入子级。
答案 2 :(得分:1)
一方面,您正在调用类方法,就像它们是独立函数一样。例如:
def findMax0():
FNode = findMin(self.root)
return FNode
应为:
def findMax0(self):
FNode = self.findMin(self.root)
return FNode
由于使用BST和Node这两个类会产生不必要的复杂性,因此很难完全理解您编写的代码。似乎至少导致了一些错误:
# Recursive
def findMin(self, root):
if self.root.right is None:
return self.root
else:
return findMin(self.root.left)
首先,它必须是self.findMin()。其次,您实际上从未引用过 root (仅引用 self.root ),因此递归将不起作用。
您似乎在递归代码中的功能和面向对象方法之间进行切换,这时选择一种样式要简单得多。例如,仅将 find()实现为它可能所属的Node方法:
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def find(self, key):
if key == self.key:
return self
if key > self.key and self.right:
return self.right.find(key)
if key < self.key and self.left:
return self.left.find(key)
如您所见,使用单个类的优点是它包含的对象也具有 find()方法,因此我们可以在子节点上递归调用。