为什么是必要的,以保持与标志迭代后期以穿越并不序或预先顺序的迭代遍历。

这是可以做到的员额以穿越没有保留访问标志?

有帮助吗?

解决方案

下面是一个命令后,请访问:

postordervisit(t)
{   if not(leaf(t))
    { postordervisit(left(t);
      postordervisit(right(t));
    }
L1: process(t);
        L2:
}

它不使用任何标志。为什么你认为一个标志是必要的吗?

也许我不明白这句话,“迭代后序遍历”。 根据对称性,如果你认为“迭代序遍历”不需要一个标志, 我主张你不得不相信“迭代后序遍历”也 标志自由的,反之亦然。

编辑:我的坏,必须在夜间迟到。 “迭代”,意思是“没有递归执行”。 OK,让你实现你自己的节点堆栈,的你要实现什么相当于返回地址的堆栈。我认为标志模拟收益的影响 解决知道是否去L1或L2未来。因为你需要这个职位顺序,由对称你需要它的预购。

编辑2010年10月:我再烂,提供的算法不是后序。修改。

其他提示

后序遍历的迭代版本可以不使用访问标记来实现,这是落实才更困难。

在这里看到迭代后序遍历两种解决方案,而无需使用任何访问标志。

http://www.leetcode.com/十分之二千零十/二进制树后阶traversal.html

如果我们开始跟简单的递归postorder算法,

def postorder1(node, f):
  # a:
    if node is None:
        return None
    postorder1(node.left, f)
  # b:
    postorder1(node.right, f)
  # c:
    f(node)

我们可以斩功能分成三部分的"a"、"b"和"c",那么天真地把它翻译成一个迭代的算法通过仿效一个虚拟的电话栈:

def postorder2(node, f):
    stack = [("a", node)]
    while stack:
        go, node = stack.pop()
        if go == "a":
            if node is not None:
                stack.append(("b", node))
                stack.append(("a", node.left))
        elif go == "b":
            stack.append(("c", node))
            stack.append(("a", node.right))
        elif go == "c":
            f(node)

从此我们观察到,叠只能修改在三个方面:

[…, a] → […, b, a]
[…, b] → […, c, a]
[…, c] → […]

这意味着:

  • "a"只能出现 最多一次的顶部栈, 而
  • "b"和"c"和出现的任何数量的时间在中间叠,有可能交织的。

因此,我们真的不需要储存"一个"内部的栈单一的变量来储存"一"就足够了。这使我们能够简化的天真的算法迭代进入更传统的形式:

def postorder3(node, f):
    stack = []
    while True:
        if node:
            stack.append((True, node))
            node = node.left
        elif stack:
            left, top = stack.pop()
            if left:
                stack.append((False, top))
                node = top.right
            else:
                f(top)
        else:
            break

布尔上的标志堆是"访问标志"。在这个例子中,我们不会存储的标志,直接节点上,但是在我们堆,但是,净效果是一样的。一些变异算法的使用"最后一次访问的节点"变量的相反,但这需要一种比较节点"的身份"(指针/平等的参考),其中我们不要假设在这里。

这是一个标志 重要 算法的一部分,因为,正如在我们的分析之前,"b"和"c"的项栈可以出现在完全是任意的方式。我们需要 一些 种信息告诉我们,我们是否应该横向右或打电话 f.

我发现,在用户的解决方案的问题的 1337c0d3r :它是一个简单的前序相反的顺序。我的解决方案使用“活动列表”在标记堆栈中的节点。

(你可以在标记标志存储在所述堆栈中。将分别张贴溶液。)

void print_postorder(Nodes const& roots)
{
    typedef std::set<Node const*> ActiveList;
    ActiveList activeNodes;
    vector<Nodes::const_iterator> stack(1, roots.begin());

    while( stack.empty() == false )
    {
        Nodes::const_iterator node = stack.back();
        ActiveList::iterator activeEntry = activeNodes.find( &*node );

        if( activeEntry == activeNodes.end() )
        {
            // This node is now active.
            activeNodes.insert( &*node );
            // Plan to visit each child.
            for( Nodes::const_reverse_iterator rchild = node->children.rbegin();
                 rchild != node->children.rend(); ++rchild )
            {
                Nodes::const_reverse_iterator rchild2 = rchild;
                Nodes::const_iterator child = (++rchild2).base();
                stack.push_back(child);
            }
        }
        else
        {
            // Post-order visit the node.
            std::size_t depth = activeNodes.size();
            for( std::size_t i = 0; i < 4 * depth; ++i )
                cout << ' ';  // Indent
            cout << node->name << endl;
            // We're finished with this node.
            activeNodes.erase( activeEntry );
            stack.pop_back();
        }
    }
}

// Try this for yourself!  Tree representation:

#include <vector>
#include <set>

struct Node;
typedef std::vector<Node> Nodes;
struct Node
{
    std::string name;
    Nodes children;
};

我相信算法显示在以前的帖子端口序遍历是因为它“进程”逛左子树前的节点。后序遍历是基本上相同逆波兰表示法,其中操作数(叶节点或子树)先于操作者(下一个较高的子树节点)。

一个校正后序遍历algorith将是:

postordervisit(t)
{   if null(t) return;    
    postordervisit(right(t));
    postordervisit(left(t);
    process(t);
}

这会前往子树的根前访问叶或子树节点。

标志是没有必要的,应该避免,因为读取器不应该修改任何东西,任何修改不会允许的并发性,例如。 这里是一个反复的后序的实现遍历在C作为宏。它适用于任何类型的树适当配置,也可以做颠倒后的顺序。整个库,它也实现了一个迭代前序遍历,是这里

#define W_TREE_FOR_EACH_POSTORDER(T,Child,self)                                                \
    W_DECLARE(W_CAT(Child,po1), T *Child)                                                      \
    W_DECLARE(W_CAT(Child,po2), T* W_ID(node) = (self))                                        \
    W_DECLARE(W_CAT(Child,po3), T** W_ID(stack) = NULL )                                       \
    W_DECLARE(W_CAT(Child,po9), int W_ID(_finish_) = 0 )                                       \
    if (W_ID(node) == NULL)                                                                    \
        ;                                                                                      \
    else                                                                                       \
        W_BEFORE(W_CAT(Child,po4), goto W_LABEL(6,Child); )                                    \
        while (!W_ID(_finish_))                                                                \
            W_BEFORE (W_CAT(Child,po5),                                                        \
              W_LABEL(6,Child):                                                                \
                while (W_ID(node)) {                                                           \
                    BOOST_PP_IF(W_REVERSED,                                                    \
                        W_TREE_FOR_EACH_IMMEDIATE_REVERSED(T,W_CAT(Child,_child), W_ID(node))  \
                            if (W_CAT(Child,_child,_ix) < W_TREE_GET_DEGREE(W_ID(node))-1)     \
                                W_DYNAMIC_STACK_PUSH( W_ID(stack),W_CAT(Child,_child) );       \
                        W_DYNAMIC_STACK_PUSH( W_ID(stack),W_ID(node) );                        \
                        W_ID(node) = W_TREE_NEXT_RIGHTMOST(W_ID(node));                        \
                        , /* else */                                                           \
                        W_TREE_FOR_EACH_IMMEDIATE(T,W_CAT(Child,_child), W_ID(node))           \
                            if (W_CAT(Child,_child,_ix) > 0)                                   \
                                W_DYNAMIC_STACK_PUSH( W_ID(stack),W_CAT(Child,_child) );       \
                        W_DYNAMIC_STACK_PUSH( W_ID(stack),W_ID(node) );                        \
                        W_ID(node) = W_TREE_NEXT_LEFTMOST(W_ID(node));                         \
                    )                                                                          \
                }                                                                              \
                W_ID(node) = W_DYNAMIC_STACK_POP( W_ID(stack) );                               \
                BOOST_PP_IF(W_REVERSED,                                                        \
                    if (W_ID(node) && W_TREE_NEXT_LEFTMOST(W_ID(node))                         \
                        && W_DYNAMIC_STACK_PEEK_SAFE(W_ID(stack),NULL) == W_TREE_NEXT_LEFTMOST(W_ID(node)) ) { \
                        W_DYNAMIC_STACK_POP(W_ID(stack));                                      \
                        W_DYNAMIC_STACK_PUSH( W_ID(stack),W_ID(node) );                        \
                        W_ID(node) = W_TREE_NEXT_LEFTMOST(W_ID(node));                         \
                        goto W_LABEL(6,Child);                                                 \
                    }                                                                          \
                    , /* else */                                                               \
                    if (W_ID(node) && W_TREE_NEXT_RIGHTMOST(W_ID(node))                        \
                        && W_DYNAMIC_STACK_PEEK_SAFE(W_ID(stack),NULL) == W_TREE_NEXT_RIGHTMOST(W_ID(node)) ) { \
                        W_DYNAMIC_STACK_POP(W_ID(stack));                                      \
                        W_DYNAMIC_STACK_PUSH( W_ID(stack),W_ID(node) );                        \
                        W_ID(node) = W_TREE_NEXT_RIGHTMOST(W_ID(node));                        \
                        goto W_LABEL(6,Child);                                                 \
                    }                                                                          \
                )                                                                              \
                Child = W_ID(node);                                                            \
                W_ID(node) = NULL;                                                             \
            )                                                                                  \
            W_AFTER(W_CAT(Child,po8),                                                          \
                W_ID(_finish_) = W_DYNAMIC_STACK_IS_EMPTY(W_ID(stack));                        \
                if (W_ID(_finish_))                                                            \
                    W_DYNAMIC_STACK_FREE(W_ID(stack));                                         \
            )                                                                                  \
            /**/

它可以用来这样。为了得到反转后顺序,重新定义W_REVERSED为1。要改变下一个字段提取操作,重新定义和W_TREE_NEXT(tree,ix)为可变参数度树木,重新定义W_TREE_GET_DEGREE(tree)

#include <wondermacros/tree/for_each.h>

struct bintree {
    struct bintree* next[2];
    const char* value;
};
struct bintree* root = ...

W_TREE_FOR_EACH_POSTORDER(struct bintree, node, root) {
        printf("%s\n", node->value);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top