二进制单词树

时间:2009-05-06 00:27:38

标签: tree iterator binary-tree

我的上一个cs类几乎没有发出吱吱声,现在我处于数据结构中。我正在从头开始构建二叉树结构,我对迭代器如何工作有点困惑。我理解它们在双链表中是如何工作的,但我不确定它是如何工作的。

6 个答案:

答案 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类中遇到了同样的问题。

我的解决方案非常简单。

递归遍历树,但将您访问的每个节点存储在另一个集合中,然后迭代该新集合。这样,编写迭代器就没有什么棘手的了。

我个人选择使用堆栈,但你可以用一个简单的数组,甚至一个链表(你说你已经有过经验)。

相关问题