我几乎完成了一个项目,让我们创建一个使用二叉树结构的字典类。然而,我坚持如何实现一个打印出树中所有元素的方法,我对二叉树没有多少经验,所以它对如何编码它感到相当困惑。
我想弄清楚的方法是一个键方法,它将遍历整个树并返回所有键的列表。我认识的人暗示我应该创建一个私有帮助函数,递归遍历树并跟踪所有键。我想创造他正在谈论的内容,但我没有世俗的想法如何编码。任何人都可以帮我编码吗?弄清楚这一点几乎可以为我完成这一切。
到目前为止,这是我的代码。 [Key:Value]
对是元组。我编写了它,并从教科书示例中获得了一些帮助来构建你在这里看到的所有内容:
class DictWithTree:
def __init__(self):
self._element = None
self._left = None
self._right = None
self._size = 0
def isempty(self):
if self._element == None:
return True
return False
def __len__(self):
return self._size
def __contains__(self,key):
path = self._tracePath(key)
return path[-1]._size > 0
def _tracePath(self,key): # taken from the textbook example and modified
if len(self) == 0 or key == self._element[0]:
return [self]
elif len(key) < len(self._element[0]):
return [self] + self._left._tracePath(key)
else:
return [self] + self._right._tracePath(key)
def __getitem__(self,key):
if len(self) == 0:
raise KeyError(key)
elif key == self._element[0]:
return self._element[1]
elif key < self._element[0]:
return self._left[key]
elif key > self._element[0]:
return self._right[key]
else:
raise KeyError(key)
def __setitem__(self,key,value):
path = self._tracePath(key)
endOfPath = path[-1]
if endOfPath._element != None:
if endOfPath._element[0] == key:
endOfPath._element = key,value
if endOfPath._size == 0: # a new element
for location in path:
location._size += 1
endOfPath._element = key,value
endOfPath._left = DictWithTree()
endOfPath._right = DictWithTree()
def clear(self):
self._element = None
self._left = None
self._right = None
self._size = 0
def pop(self,key):
value = self[key]
self._remove(key)
return value
def popitem(self): # returns the 'last' item in the dictionary,
if self.isempty(): # (i.e. the largest key in the dictionary)
return KeyError("There are no keys in the dictionary")
elif self._right._element == None:
return self._element
else:
return self._right.popitem()
def _remove(self,key):
path = self._tracePath(key)
endOfPath = path[-1]
if endOfPath._size > 0:
for location in path:
location._size -= 1
if len(endOfPath._left) == 0:
endOfPath._promoteChild(endOfPath._right)
elif len(endOfPath._right) == 0:
endOfPath._promoteChild(endOfPath._left)
else:
endOfPath._element = endOfPath._left.pop()
def _promoteChild(self,child):
self._element = child._element
self._left = child._left
self._right = child._right
答案 0 :(得分:2)
您需要做的就是创建一个辅助方法visitAllSubnodes(node)
,它对当前节点执行某些操作,然后在左右子节点上递归调用自身。 visitAllSubnodes(node)
可以做什么,在你的情况下它可能是print(node._element)
,但你可以使你的功能非常模块化,例如
def visitAllSubnodes(node, whatToDoAtEachNode):
whatToDoAtEachNode(node)
visitAllSubnodes(node._left, whatToDoAtEachNode)
visitAllSubnodes(node._right, whatToDoAtEachNode)
def printAllElements(node):
visitAllSubnodes(node, lambda x:print(x))
要实际返回某些内容,您需要使用更高阶函数和闭包的概念。例如,您可以创建一个定义私人个人累加器(您添加的列表)的函数,以及该私有个人累加器所属的另一个函数,然后返回该函数。
所以例如,每次遍历树时,你可以调用这个更高阶的函数,让它调用它makeFunctionWhichKeepsTrackOfWhatHasBeenPassedIntoIt()
,它返回一个函数来跟踪传递给它的函数,以及累加器。我会提供更多信息,但这将是问题集的重点。 =)
答案 1 :(得分:0)
这应该这样做
def allKeys(d):
toVisit = []
toVisit.append(d)
while (len(toVisit)>0):
x = toVisit.pop()
if x._element:
yield x._element[0]
if x._left:
toVisit.append(x._left)
if x._right:
toVisit.append(x._right)
对于有序遍历,您需要一个递归soln,如树遍历中的维基百科entry中所示。
答案 2 :(得分:0)
对于树遍历,通常人们会进行广度优先遍历(BFT)或深度优先遍历(DFT)。
在BFT中你使用一个队列来记忆你离开的地方,在DFT中你使用堆栈记住你离开的地方。如果你知道队列和堆栈的本质,理解BFT和DFT只是小菜一碟,否则请阅读Breadth-first search和Depth-first search,顺便说一句,遍历树的代码是通常不超过10行证明它们是多么容易。
答案 3 :(得分:0)
使用Python 3 yield from
进行递归有序树遍历的另一种解决方案:
def traverse(tree):
if tree.left is not None:
yield from traverse(tree.left)
yield tree.value
if tree.right is not None:
yield from traverse(tree.right)
print(list(traverse(tree_root)))
我认为它更具可读性和概念简单性。我希望它会对某人有所帮助。