繁体   English   中英

二叉树中的无​​堆栈预订序遍历

[英]Stackless pre-order traversal in a binary tree

是否可以在二叉树上执行迭代 * 预订 *遍历而不使用节点堆栈或“访问”标志?

据我所知,这种方法通常要求树中的节点有指向其父节点的指针。 现在,可以肯定的是,我知道如何使用父指针访问标志执行预先遍序遍历从而消除了对迭代遍历的任何节点堆栈的需求。

但是,我想知道访问标志是否真的有必要。 如果树有很多节点,它们会占用大量内存。 而且,如果二进制树的许多预订树遍历同时并行进行,那么拥有它们将没有多大意义。

如果可以执行此操作,一些伪代码或更好的短C ++代码示例将非常有用。

编辑:我特别希望使用递归的前序遍历。 我的问题的上下文是我在GPU上构建了一个八叉树(就像一棵二叉树)。 我想启动许多线程,每个线程独立并行地进行树遍历。

首先,CUDA不支持递归。 值得注意的是,访问标志的概念仅适用于单个遍历。 由于许多遍历同时进行,因此在节点数据结构中具有visit-flags字段是没有用的。 它们仅在CPU上有意义,其中所有独立树遍历都可以序列化。 更具体地说,在每次树遍历之后,我们可以在执行另一个预订树遍历之前将被访问标志设置为false。

您可以使用此算法,该算法仅需要父指针而无需额外存储:

对于内部节点,预先遍历遍历中的下一个节点是其最左边的子节点。

对于叶节点:在树中继续向上,直到您来自具有两个子节点的节点的左子节点。 那个节点的右子将成为下一个遍历的节点。

function nextNode(node):
    # inner node: return leftmost child
    if node.left != null:
        return node.left
    if node.right != null:
        return node.right

    # leaf node
    while (node.parent != null)
        if node == node.parent.left and node.parent.right != null:
            return node.parent.right
        node = node.parent

    return null  #no more nodes

您可以根据前序遍历为每个叶节点指定一个指向下一个节点的指针。

例如,给定二叉树:

          A
         / \
        B   C
       / \
      D   E
           \
            F

D需要存储指向E的指针,F需要存储指向C的指针。然后,您可以简单地遍历遍历树,就好像它是链表一样。

通过在左右子树节点中存储相同的指针,您可以在没有额外存储的情况下完成此操作。 由于树中不允许这样的结构(这会使它成为DAG),因此可以安全地推断出所有“子”指针指向同一位置的任何节点都是叶节点。

您可以在每个节点添加一个位,表示第一个子分支添加是向左还是向右...然后,遍历树允许在每个分支处选择原始方向。

如果您坚持这样做,您可以在树中编号每个可能的路径,然后将每个工作者设置为遵循该路径。

你的编号方案可以简单地说,每个零位意味着占用左子,每一位意味着占用正确的孩子。 要执行深度优先搜索,请将数字从最低有效位处理到最高有效位。

虽然没有必要提前知道树的深度,但如果不这样做,则需要处理所有其他数字在数字完全消耗之前到达叶子的情况。

有一个hack使用{ - > left, - > right}指针的绝对值来编码每个节点一位 它需要第一遍才能获得初始指针 - “极性”。 它似乎被称为DSW。 您可以在此https://groups.google.com/group/comp.programming/browse_thread/thread/3552ea0af2006b28/6323076923faec26?hl=nl&q=tree+transversal&lnk=nl&usenet主题中找到更多内容。

我不知道它是否可以扩展为四叉树或八叉树,我很怀疑它是否可以扩展到多线程访问。 添加父指针可能更容易......

您可能想要考虑的一个方向是在遍历树时删除树的节点并将这些节点插入到新树中。 如果按顺序插入节点,则新树将完全相同。 但这里的问题是当你删除项目时如何保持原始树的完整性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM