我的上一个cs类几乎没有发出吱吱声,现在我处于数据结构中。我正在从头开始构建二叉树结构,我对迭代器如何工作有点困惑。我理解它们在双链表中是如何工作的,但我不确定它是如何工作的。
答案 0 :(得分:1)
所有其他答案都是关于如何在树结构上实现迭代器的技术讨论。但是,正如我理解你的问题,你似乎无法理解树遍历概念的机制,而不仅仅是实现。换句话说,你不要“grok”树遍历。最重要的是获得一个好的伪代码算法来遍历二叉树,一支铅笔,一张纸,并找出一个例子。构建一个简单的二叉树,然后通过机械跟随伪代码自己遍历它。您应该使用第二张纸来写出stack。也就是说,因为正在等待子函数返回而被调用的每个函数的状态。
请记住,当你这样做时,树是一个非常优雅的结构。它看起来很复杂,但在每个节点都很简单。要对树中的所有元素执行操作,只需在树的根处执行该操作,然后让操作在该根的每个子节点上调用,这些子节点本身就是子树的根。自己制定一个例子将有很长的路要走,让你的思想理解并接受递归。如果你发现它很难,不要被困惑。递归很奇怪。一开始这是一个很难的概念,但有必要理解和使用树木。
以下是您可以用来启动的示例(ASCII art)树:
F / \ / \ D H / \ / \ B E G I / \ A C
一个简单的伪代码算法,可用于以正确的有序遍历编写所有字母。
procedure traverse(node) if node is not null: traverse(node.left) write node.letter traverse(node.right) else: do nothing
你甚至可以从更简单的树开始。如果树只由节点D,F和H组成怎么办?如果它只是F怎么办?空值?尝试这些简单的例子,然后处理更大的树。当你已经弄清楚如何一致和正确地做到这一点时,你不仅会对迭代器实现中发生的事情有一个非常好的感觉,你将会更好地理解递归的力量。
答案 1 :(得分:0)
“Iterator”是什么意思?如果你只需要迭代树,你可以递归地执行: http://en.wikipedia.org/wiki/Tree_traversal#Sample_implementations
如果必须提供类似C#或Java的IEnumerator接口或想要节省堆栈空间,请使用: http://en.wikipedia.org/wiki/Tree_traversal#Queue-based_level_order_traversal 您可以在C#中使用yield,或者将while循环轻松转换为迭代器所需的“GetNext”方法。
答案 2 :(得分:0)
我可以递归地做。我只是想在脑海中想象你是如何从一片叶子移到另一片叶子的,因为从根部开始有两种选择,下一步去哪里,之后它只增加2 ^ n次。这个如何运作的顺序令我感到困惑。
答案 3 :(得分:0)
迭代树有两种主要方式。我在Iterative tree walking发布了一些示例Python代码示例。
答案 4 :(得分:0)
在二叉树中,每个节点都会存储一些值并有2个子节点,例如左右节点。现在,遍历树的一种方法是从顶部开始,遍历左边的子节点,查看此节点的值,然后遍历右边的子节点。
遍历孩子表示(递归): 1)遍历左孩子 2)查看节点的值 3)遍历正确的孩子
这是深度优先遍历,因此对于每个节点,您首先使用'或'看'左子的值,然后是当前节点的值,最后是右子的值。
对于广度优先遍历,您将从root开始,查看节点的值,然后将其子节点(如果存在)推入队列。然后循环,同时在队列中有一个节点,从队列的前面获取节点并重复:查看它的值,如果它有子节点,则在队列末尾推送它们。
python中的示例:
#!/usr/bin/env python
class Node:
def __init__(self, val = 0):
self.value = val
self.left = None
self.right = None
def __str__(self):
return "%d" % (self.value)
def dfs(node = None):
if node is None: return
dfs(node.left)
print node
dfs(node.right)
def bfs(root = None):
if root is None: return
nodes = []
nodes.append(root)
while len(nodes):
current = nodes[0]
print current
nodes.remove(current)
if current.left is not None:
nodes.append(current.left)
if current.right is not None:
nodes.append(current.right)
def main():
root = Node(0)
root.left = Node(10)
root.right = Node(20)
l = root.left
l.left = Node(100)
l.right = Node(101)
r = root.right
r.left = Node(200)
r.right = Node(201)
dfs(root)
bfs(root)
if __name__ == '__main__':
main()
# example tree constructed:
# 0
# 10 20
# 100 101 200 201
# dfs (depth first) traversal:
# 100
# 10
# 101
# 0
# 200
# 20
# 201
# bfs (breadth first) traversal:
# 0
# 10
# 20
# 100
# 101
# 200
# 201
答案 5 :(得分:0)
我在Data Structures类中遇到了同样的问题。
我的解决方案非常简单。
递归遍历树,但将您访问的每个节点存储在另一个集合中,然后迭代该新集合。这样,编写迭代器就没有什么棘手的了。
我个人选择使用堆栈,但你可以用一个简单的数组,甚至一个链表(你说你已经有过经验)。