【问题标题】: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 节点的二叉树,
打印出每个节点的密钥。在树本身之外使用不超过恒定的额外空间,并且在此过程中不要修改树,即使是临时的。
我试图找到一个解决方案,但一无所获......(我也在谷歌搜索这本书的解决方案,但这个问题没有包含在其中,可能是因为它是在更高版本中添加的)。
【问题讨论】:
标签:
algorithm
tree
binary-tree
【解决方案1】:
这里有一个解决方案:
- 让
current存储当前访问的节点(初始化到树的根节点)
- 让
origin 表示我们如何到达当前节点。它是FROM_PARENT、FROM_LEFT_CHILD、FROM_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;
}