无递归、无堆栈且不改变树的树遍历

Posted

技术标签:

【中文标题】无递归、无堆栈且不改变树的树遍历【英文标题】:Tree Traversal without recursion and without stack and without changing the Tree 【发布时间】:2014-08-20 11:17:40 【问题描述】:

本题出自《算法导论3》一书:

**二叉树中的每个节点都有4个属性:key,left,right,parent

编辑:二叉树存储为链接节点,每个节点都具有我提到的 4 个属性。

写一个 O(n) 时间的非递归过程,给定一个 n 节点的二叉树, 打印出每个节点的密钥。在树本身之外使用不超过恒定的额外空间,并且在此过程中不要修改树,即使是临时的。

我试图找到一个解决方案,但一无所获......(我也在谷歌搜索这本书的解决方案,但这个问题没有包含在其中,可能是因为它是在更高版本中添加的)。

【问题讨论】:

你可能想看看这个:***.com/questions/5502916/…. @dguan 这个算法在过程中修改了树。 【参考方案1】:

这里有一个解决方案:

current存储当前访问的节点(初始化到树的根节点) 让origin 表示我们如何到达当前节点。它是FROM_PARENTFROM_LEFT_CHILDFROM_RIGHT_CHILD 之一。 (初始化为FROM_PARENT

算法:

如果我们从顶部来,我们打印钥匙然后向左走 如果我们从左边回来,就往右走 如果我们从正确的位置返回,就往上走。

 

origin = FROM_PARENT;
current = root;

while (current != null) 

    switch (origin) 

    case FROM_PARENT:
        System.out.println(current.key);
        if (current.left != null)
            goLeft();
        else
            origin = FROM_LEFT_CHILD;
        break;

    case FROM_LEFT_CHILD:
        if (current.right != null)
            goRight();
        else
            origin = FROM_RIGHT_CHILD;
        break;

    case FROM_RIGHT_CHILD:
        goToParent();
        break;
                

在哪里

static void goToParent() 
    if (current.parent == null) 
        current = null;
        return;
    
    origin = current == current.parent.left ? FROM_LEFT_CHILD
                                            : FROM_RIGHT_CHILD;
    current = current.parent;


static void goLeft() 
    origin = FROM_PARENT;
    current = current.left;


static void goRight() 
    origin = FROM_PARENT;
    current = current.right;

【讨论】:

以上是关于无递归、无堆栈且不改变树的树遍历的主要内容,如果未能解决你的问题,请参考以下文章

同学,二叉树的各种遍历方式,我都帮你总结了,附有队列堆栈图解(巩固基础,强烈建议收藏)

C++如何实现二叉树的递归遍历?

二叉树的中序先序后序遍历非递归遍历算法(使用堆栈,用循环实现)

leetcode404-----简单的树的遍历

在C中没有递归和堆栈的遍历树

在没有递归的情况下遍历非二叉树的算法是什么(使用堆栈)[重复]