首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >树根节点的迭代后序遍历断裂

树根节点的迭代后序遍历断裂
EN

Stack Overflow用户
提问于 2015-09-24 17:41:06
回答 2查看 183关注 0票数 1

我实现了一个算法,用于迭代地打印二叉树的后置遍历。整个算法可以工作,但当它碰到树根时,它会进入无限循环。

谁能给我指明正确的方向吗?我在这个问题上已经困了两天了。

代码语言:javascript
复制
void postorder_nonrec_2(treenode *root)
{
    stack_t *s;
    stack_init(&s, 100);
    treenode *temp = root;

    while(1)
    {
        while(root)
        {
            push(s, root);
            root = root -> left;
        }

        if(stack_isEmpty(s))
            break;

        if(!top(s) -> right)
        {
            root = pop(s);
            printf("%d ", root -> data);

            if(root == top(s) -> left)
            {
                root = top(s) -> right;
            }
            else if(root == top(s) -> right)
            {
                printf("%d ", pop(s) -> data);

                root = NULL;
            }
        }
        else
        {
            root = top(s) -> right;
        }

    }
}
EN

Stack Overflow用户

回答已采纳

发布于 2015-09-26 16:06:59

也许在您使用的测试用例中,只有根处有一个无限循环,但我认为无限循环也可能发生在树的其他地方,这取决于特定的树。

问题是,我认为,当右侧存在子元素时,不能正确地继续弹出堆栈。

考虑一个简单的例子,其中我们有一个根节点1,其中一个左子节点0,一个右子节点2,并且假设2有一个名为3的右子节点。

在第一个循环中,我们将1和0推到堆栈上。那么0没有左子,所以根变成空。堆栈不是空的,所以我们继续。0位于堆栈的顶部,没有正确的子级,因此我们输入if语句的第一个分支。然后我们打印出0,因为0是1的左子-- 1现在是堆栈的顶部--根目录变成2。

在这一点上,我们回到顶端。2是根,并被推到堆栈上。2没有左子,所以根目录变为空。堆栈不是空的。2在堆栈的顶部。它有一个正确的子项,所以我们输入if语句的第二个分支。这就形成了3的根。

我们回到外环的顶端。3是根,然后被推到堆栈上。3没有左子,所以根变为空。堆栈不是空的。3没有正确的子项,所以我们输入if语句的第一个分支。我们打印出3,因为3是2的正确子-- 2现在在堆栈的顶部--我们从堆栈中弹出2,打印出2,根目录变为空。

我们回到循环的顶端。根已经是空的,所以没有任何东西被推到堆栈上。堆栈不是空的。1在堆栈的顶部。此时,正确的做法是从堆栈中弹出1,因为我们已经处理了它的正确子级;但是,1位于堆栈的顶部,并且确实有一个正确的子级,因此我们输入if语句的第二个分支,2成为根。情况与前两段完全相同,堆栈上只有1个元素,根元素有2个,因此我们得到了一个无限循环。

如果我们更改了示例,使3也有一个正确的子程序名为4,那么,如果我正确地阅读,我们将永远不会打印出2,并循环打印出4和3。

要纠正这个问题,您应该继续弹出堆栈,只要您正在处理的元素是堆栈顶部的正确子元素。我还没有编译或测试过这一点,但我认为编写这样的东西是可行的

代码语言:javascript
复制
    if (!top(s) -> right)
    {
        root = pop(s);
        printf("%d ", root -> data);

        while (!stack_isEmpty(s) && root == top(s) -> right)
        {
            root = pop(s);
            printf("%d ", root -> data);
        }
        if (!stack_isEmpty(s) && root == top(s) -> left)
        {
            // checking root == top(s) -> left is probably redundant,
            // since the code is structured so that root is either
            // a child of top(s) or null if the stack is not empty
            root = top(s) -> right;
        }
        else
        {
            root = NULL;
            // could actually break out of outer loop here, but
            // to be more consistent with code in the question
        }
    }
票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32767670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档