有没有人能给我一个不使用递归和栈的中序遍历二叉树的解决方案?
第二次编辑:我认为这是正确的。除了通常的node.left_child和node.right_child之外,还需要node.isRoot、node.isLeftChild和node.parent。
state = "from_parent"
current_node = root
while (!done)
switch (state)
case "from_parent":
if current_node.left_child.exists
current_node = current_node.left_child
state = "from_parent"
else
state = "return_from_left_child"
case "return_from_left_child"
if current_node.right_child.exists
current_node = current_node.right_child
state = "from_parent"
else
state = "return_from_right_child"
case "return_from_right_child"
if current_node.isRoot
done = true
else
if current_node.isLeftChild
state = "return_from_left_child"
else
state = "return_from_right_child"
current_node = current_node.parent
如果您的树节点具有父引用/指针,则在遍历过程中跟踪您来自哪个节点,以便您可以决定下一步去哪里。
在Python中:
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
self.parent = None
if self.left:
self.left.parent = self
if self.right:
self.right.parent = self
def inorder(self):
cur = self
pre = None
nex = None
while cur:
if cur.right and pre == cur.right:
nex = cur.parent
elif not cur.left or pre == cur.left:
yield cur.value # visit!
nex = cur.right or cur.parent
else:
nex = cur.left
pre = cur
cur = nex
root = Node(1,
Node(2, Node(4), Node(5)),
Node(3)
)
print([value for value in root.inorder()]) # [4, 2, 5, 1, 3]
如果您的树节点没有父引用/指针,则可以进行所谓的Morris遍历,它会暂时改变树的结构,使没有右子节点的节点的right
属性暂时指向其中序后继节点:
在Python中:
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def inorder(self):
cur = self
while cur:
if cur.left:
pre = cur.left
while pre.right:
if pre.right is cur:
# We detect our mutation. So we finished
# the left subtree traversal.
pre.right = None
break
pre = pre.right
else: # prev.right is None
# Mutate this node, so it links to curr
pre.right = cur
cur = cur.left
continue
yield cur.value
cur = cur.right
root = Node(1,
Node(2, Node(4), Node(5)),
Node(3)
)
print([value for value in root.inorder()])
struct node {
int value;
node *left;
node *right;
node *parent;
};
node *tree_first(node *root) {
while(root && root->left)
root = root->left;
return root;
}
node *tree_next(node *p) {
if(p->right)
return tree_first(p->right);
while(p->parent) {
if(!p->parent->right || p->parent->right != p)
return p->parent;
else p = p->parent;
}
return 0;
}
可以的。为了做到这一点,您需要一个父指针以便上升树。
recursion //going into
recursion
recursion
recursion
recursion //going back up
recursion
recursion
recursion
所以当递归结束时,您已经按相反的顺序打印了二叉树的选择侧。