在python中使用OOP和递归从前缀创建二叉树



我对编程很陌生,我一直在尝试从前缀表达式创建二叉树。我已经独自尝试了20多个小时,用youtube视频和谷歌,但似乎仍然没有正确。

我已经做了什么:

class Node:
def __init__(self,lst):
self.parent=None
self.lst=lst
self.left=None
self.right=None
self.root=None

def create_tree(self,lst):
for i in range(len(lst)):
if lst[i].isdigit():
node=Node(lst)
else:
self.parent=lst[i]
self.left=self.create_tree(lst[i+1])
self.right=self.create_tree(lst[i+2])
lst.remove(self.parent)
lst.remove(self.left)
lst.remove(self.right)
node=Node(lst)
return lst
lst=["+","2","3"]
node=Node(lst)
node.create_tree(lst)

有人能向我解释一下我错过了什么或做错了让这个工作吗?它需要在一个类中,我想用递归来解决这个问题,而不是堆栈。如有任何帮助,不胜感激。

这段代码有很多需要注释的地方,恐怕没有多少可以保留下来。这是一个不完整的问题列表:

  • Node实例不应该有root成员。这需要将根引用复制到所有树中的节点。这使得事情很难维护,而且不是这样做的。相反,定义表示树(而不仅仅是节点)的第二个类。该类将具有root属性。

  • 一个Node当然不应该得到lst的引用。该列表仅包含预订单,在节点中根本没有任何作用。

  • 虽然对于某些用途来说,在Node实例中有一个parent引用是很好的,但很多时候这是不必要的:当你从根开始导航树时,你总是知道你从哪里来,所以当你到达一个节点时,你已经知道它的父节点是什么(你刚刚从那里来)。所以存储通常只是增加工作量,而不是解决任何有用的问题。

  • 当你进行递归时,你不应该在整个列表上使用for循环。要么在列表上使用循环迭代而不进行递归,要么使用递归——将列表的其余部分传递给它——并且在同一列表上不进行循环。

  • node=Node(lst)是错误的:你不想为整个列表创建节点。您只需要为其中一个值设置一个节点,即lst[i]

  • self.parent=lst[i]是错误的:你不想引用一个列表条目,而是一个节点实例。但正如我上面指出的,你并不需要这个parent,所以删掉它。

  • remove的调用是错误的,有几个原因:

    • 当你从你也在迭代的列表中删除时,它主要导致问题。
    • 由于在递归调用时已经省略了lst[0],因此不需要删除任何内容。
  • return lst是错误的,因为调用者期望一个节点,而不是一个列表。此外,if块中没有发生return,因此您返回的None也是错误的。

这不是一个完整的问题列表,但它表明您需要重写大部分代码。

在这里,我将建议在输入列表上使用迭代器:使用next方法,您可以轻松地获得列表的下一个值,而不需要摆弄索引和切片:

class Node:
# Constructor accepts two optional arguments so to set left and right subtrees
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
class Tree:
def __init__(self, lst):
it = iter(lst) # Create an iterator over the list

def create_tree():  # Helper function
value = next(it, None)
if value is None:  # No more value
return None
if value.isdigit():  # We need a leaf node
return Node(value)
# Use recursion to build the left and right subtree and
#     create a Node instance with them as children
return Node(value, create_tree(), create_tree())
self.root = create_tree()

你的主代码可以是:

lst = ["+","2","3"]
tree = Tree(lst)

注意:您可能需要添加一个函数来显示树。

最新更新