Inorder Tree Traversal without recursion and without stack!

Using Morris Traversal, we can traverse the tree without using stack and recursion. The idea of Morris Traversal is based on Threaded Binary Tree. In this traversal, we first create links to Inorder successor and print the data using these links, and finally revert the changes to restore original tree.

1. Initialize current as root
2. While current is not NULL
If current does not have left child
a) Print current’s data
b) Go to the right, i.e., current = current->right
Else
a) Make current as right child of the rightmost node in current's left subtree
b) Go to this left child, i.e., current = current->left

Although the tree is modified through the traversal, it is reverted back to its original shape after the completion. Unlike Stack based traversal, no extra space is required for this traversal.

What is “pre” used for? It has no use whatsoever in this algorithm. It only appears on the left hand side of the operations

Vulkum

oh, nvm, missed the assignment line

Ashutosh Litelo

Dint understand the restoration part.can u explain wid a dry run

/* Revert the changes made in if part to restore the original
tree i.e., fix the right child of predecssor */
else
{
pre->right = NULL;
printf(” %d “,current->data);
current = current->right;
} /* End of if

This will cause the infinite loop.. better use some flag as pointed out by some one below in comment list.

ibn

1. Initialize current as root
2. While current is not NULL
If current does not have left child
a) Print current’s data
b) Go to the right, i.e., current = current->right
Else
a) Make current as right child of the rightmost node in current’s left subtree
b) Go to this left child, i.e., current = current->left

For the given example tree where ‘4’ is the left most leaf node, the above code fragment prints ‘4’ and assigns current to null and hence the while loop breaks, after printing ‘4’. The tree is not completely traversed. Am I missing something here? Please help me.

nikhil

I have noticed the same thing.
Something is missing in the algo.

aygul

Yes you are mssing the point that in the previous iteration right pt of 4 was set to 2. In the next iteration current->right will be 2 and it will be printed in the inner else part just after the right of node 4 is set to null to put the tree back to original. Is it clear now ?

Try running given code for below tree:
[You will see it printing wrong data and infinitely looping]

A
B C
D E F
G K

Morris traversal gets stuck , after visiting left subtree of A and then while traversing A onwards.
It will try to reLink E->A continously and gets shifted to left subtree of A (which is already traversed)

srvkumar

May be the method works fine for ‘complete trees’. But I am not sure, haven’t tested it.

srvkumar

May be the method works fine only for ‘complete trees’. But I am not sure, haven’t tested it.

Here’s a challenge: How can you do that with O(1) space complexity without changing the tree in the process when in addition to the regular operations you can do with trees, you can also go to a parent node (parent of root is NULL). Is it possible?

@SANDEEP, GEEKSFORGEEKS, KARTIK…..CAN ANY ONE OF YOU PROOVE TEH TIM E COMPLEXITY OF MORRIS TRAVESRAL IS O(NLOGN)…???

Tony

Algorithm:
1. Traverse LEFT until the left child is null and push the current node into stack. (This loop continues until the stack is empty)
2. Pop the stack and process the current node.
3. Go to the right child.

Morris algorithm runs at O(nlgn) not O(n). I could not think how it runs in O(n) time. Any idea? Thanks

kunal

dude, any algortithm which does tree traversal will definitely take at least O(n) time.

qi li

Kunal, my pointer is not saying tree traveral takes at least O(n) time. My question is the complexity of the Morris Algorithm. I think it runs at O(nlgn), which is slower than recursive traversal except Morris approach has space advantage.

mrn

it takes O(n) time. reference : adam drozdek (data structures)

alok maurya

good one !

qi li

this part is duplicated when backing from left child to its parent

while(pre->right != NULL && pre->right != current)
pre = pre->right;

Any idea how to remove the duplication finding the right most child when backing from left child to its parent? Thanks