Can anyone give me a solution开发者_如何学C for traversing a binary tree in inorder without recursion and without using a stack?
Second edit: I think this is right. Requires node.isRoot, node.isLeftChild, and node.parent, in addition to the usual node.left_child and node.right_child.
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
1. Double threaded tree
If your tree nodes have parent references/pointers, then keep track of which you node you came from during the traversal, so you can decide where to go next.
In 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]
2. Single threaded tree
If your tree nodes do not have parent references/pointers, then you can do a so-called Morris traversal, which temporarily mutates the tree, making the right
property -- of a node that has no right child -- temporarily point to its inorder successor node:
In 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()])
Since traversing a binary tree requires some kind of state (nodes to return after visiting successors) which could be provided by stack implied by recursion (or explicit by an array).
The answer is no, you can't. (according to the classic definition)
The closest thing to a binary tree traversal in an iterative way is probably using a heap
EDIT: Or as already shown a threaded binary tree ,
Yes, you can. In order to do this, you would require a parent pointer in order to ascend the tree.
Start with tree_first(), continue with tree_next() until get NULL. Full code: https://github.com/virtan/tree_closest
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;
}
As someone here already stated, it is possible, but not without the parent pointer. The parent pointer basically allows you to traverse "the path" if you want, and therefore print-out the nodes. But why does recursion works without parent pointer? Well if you understand recursion it goes something like this(imagine the recursion stack):
recursion //going into
recursion
recursion
recursion
recursion //going back up
recursion
recursion
recursion
So when the recursion ends you then have printed the chosen side of the binary tree in reversed order.
精彩评论