我正在尝试在Python中为非二叉树实现一个迭代器类。构造迭代器后,可以重复调用其
下面是树的基本
这些都很好,但我想摆脱对
我需要的所有状态应该在迭代器中处理,但我不知道如何做到这一点。为整个树保留已访问列表是不可扩展的,也是不可能的,因此必须有一个巧妙的方法来使用堆栈。
尤其令我困惑的是这一点——由于
更新-这里是一个小测试:
next()
函数以深度优先顺序遍历树(例如此顺序),最后当没有节点时返回None
。下面是树的基本
Node
类:class Node(object):
def __init__(self, title, children=None):
self.title = title
self.children = children or []
self.visited = False
def __str__(self):
return self.title
如上所示,我在第一种方法中为节点引入了一个visited
属性,因为我没有看到其他的解决方法。有了这个额外的状态,Iterator
类就像这样:
class Iterator(object):
def __init__(self, root):
self.stack = []
self.current = root
def next(self):
if self.current is None:
return None
self.stack.append(self.current)
self.current.visited = True
# Root case
if len(self.stack) == 1:
return self.current
while self.stack:
self.current = self.stack[-1]
for child in self.current.children:
if not child.visited:
self.current = child
return child
self.stack.pop()
这些都很好,但我想摆脱对
visited
属性的需求,而不使用递归或任何其他对Node
类的修改。我需要的所有状态应该在迭代器中处理,但我不知道如何做到这一点。为整个树保留已访问列表是不可扩展的,也是不可能的,因此必须有一个巧妙的方法来使用堆栈。
尤其令我困惑的是这一点——由于
next()
函数当然会返回,那么我怎么能记住我去过哪里,而又不标记任何东西或使用过量的存储空间呢?直觉上,我想循环遍历子节点,但是当next()
函数返回时,这种逻辑就被打破/忘记了!更新-这里是一个小测试:
tree = Node(
'A', [
Node('B', [
Node('C', [
Node('D')
]),
Node('E'),
]),
Node('F'),
Node('G'),
])
iter = Iterator(tree)
out = object()
while out:
out = iter.next()
print out
A B C D E F G None
。顺便说一下,实现 @mgilson 的生成器解决方案作为next()
主体会导致无限循环,但这可能只是我对生成器的适应/理解不足。 - normanfor
循环中遍历它,而不是某种while循环。我没有看到你的while循环在任何地方起作用,因为你没有捕获StopIteration
异常。) - mgilson