What if you could walk through a tree without carrying any extra notes or tools?
Why Morris Traversal Inorder Without Stack in DSA C#?
Imagine you have a big family tree drawn on paper, and you want to visit each family member in order from oldest to youngest. You try to remember where you left off by writing notes on sticky notes (like a stack), but you keep losing them or running out of space.
Using sticky notes (a stack) to remember where you are is slow and messy. You might lose track, run out of notes, or get confused. It also takes extra space and effort to keep track of all these notes while walking through the tree.
Morris Traversal lets you visit each family member in order without using any sticky notes or extra memory. It cleverly changes the tree paths temporarily to remember where to go next, then restores the tree back to normal. This way, you can walk through the tree smoothly without extra space.
void InorderTraversal(Node root) {
Stack<Node> stack = new Stack<Node>();
Node current = root;
while (current != null || stack.Count > 0) {
while (current != null) {
stack.Push(current);
current = current.Left;
}
current = stack.Pop();
Console.Write(current.Value + " ");
current = current.Right;
}
}void MorrisInorderTraversal(Node root) {
Node current = root;
while (current != null) {
if (current.Left == null) {
Console.Write(current.Value + " ");
current = current.Right;
} else {
Node predecessor = current.Left;
while (predecessor.Right != null && predecessor.Right != current) {
predecessor = predecessor.Right;
}
if (predecessor.Right == null) {
predecessor.Right = current;
current = current.Left;
} else {
predecessor.Right = null;
Console.Write(current.Value + " ");
current = current.Right;
}
}
}
}You can traverse a binary tree in order using only the tree itself, without extra memory or complicated tools.
When a device has very limited memory, like a small sensor or embedded system, Morris Traversal helps process tree data efficiently without extra storage.
Morris Traversal visits nodes in order without using a stack or recursion.
It temporarily changes tree links to remember paths, then restores them.
This saves memory and simplifies traversal in memory-limited situations.
Practice
Solution
Step 1: Understand Morris Traversal space usage
Morris Traversal uses threaded binary trees to avoid recursion or stack, so it uses O(1) extra space.Step 2: Compare with other methods
Recursive and stack-based traversals use O(h) space where h is tree height, so Morris Traversal saves memory.Final Answer:
It uses no extra space for stack or recursion. -> Option CQuick Check:
Space complexity = O(1) [OK]
- Thinking it is faster than recursive traversal
- Assuming it only works on BSTs
- Believing it permanently changes the tree
Solution
Step 1: Identify starting point for traversal
Morris traversal starts from the root node to cover the entire tree.Step 2: Check initialization correctness
Initializing current as root ensures traversal begins at the tree's root.Final Answer:
TreeNode current = root; -> Option AQuick Check:
Start traversal at root node [OK]
- Starting from null causes no traversal
- Starting from left or right child misses nodes
2
/ \
1 3
Assuming the traversal prints node values separated by spaces.Solution
Step 1: Understand inorder traversal order
Inorder traversal visits left subtree, root, then right subtree.Step 2: Apply Morris traversal order on given tree
Left child 1, then root 2, then right child 3 results in "1 2 3".Final Answer:
1 2 3 -> Option BQuick Check:
Inorder = left-root-right = 1 2 3 [OK]
- Confusing preorder or postorder with inorder
- Misreading tree structure
while (current != null) {
if (current.left == null) {
Console.Write(current.val + " ");
current = current.right;
} else {
TreeNode predecessor = current.left;
while (predecessor.right != null && predecessor.right == current) {
predecessor = predecessor.right;
}
if (predecessor.right == null) {
predecessor.right = current;
current = current.left;
} else {
predecessor.right = null;
Console.Write(current.val + " ");
current = current.right;
}
}
}
What is the bug in this code?Solution
Step 1: Analyze inner while loop condition
The loop should continue while predecessor.right != null && predecessor.right != current to reach the rightmost node in left subtree.Step 2: Check given condition correctness
The code uses predecessor.right == current, which fails to traverse the right chain properly, as it only continues if already threaded back.Step 3: Why other options are wrong
A: left null is handled in if. C: reset happens in else. D: print placement is correct for inorder.Final Answer:
The inner while loop should check predecessor.right != current instead of predecessor.right == current. -> Option DQuick Check:
Loop condition must be != null && != current [OK]
- Confusing loop condition signs
- Forgetting to reset threaded pointers
- Misplacing print statements
Solution
Step 1: Identify when nodes are visited in Morris traversal
Nodes are visited (printed) when current.left is null or after removing threaded link.Step 2: Counting nodes correctly
Incrementing counter when printing nodes ensures counting all nodes exactly once.Step 3: Why other options fail
Incrementing only on creating or removing threaded links misses nodes or counts duplicates.Final Answer:
Increment a counter each time you print a node's value during traversal. -> Option AQuick Check:
Count nodes when visiting them [OK]
- Counting on threaded link creation/removal
- Counting only left-null nodes
- Missing some nodes in count
Ready to prove it?
Pass the test and this pattern moves unknown
