📖 Scenario: Imagine you have a family tree represented as a binary tree. You want to visit each family member in order from left to right without using extra memory like a stack or recursion.
🎯 Goal: Build a Go program that performs an inorder traversal of a binary tree using Morris Traversal technique, which uses no stack or recursion, and prints the node values in order.
📋 What You'll Learn
Define a binary tree node struct called Node with Val, Left, and Right fields
Create a sample binary tree with exact nodes and structure
Implement Morris inorder traversal without using stack or recursion
Print the node values in inorder sequence separated by spaces
💡 Why This Matters
🌍 Real World
Morris traversal is useful in systems with limited memory where recursion or stack usage is costly, such as embedded systems or memory-constrained devices.
💼 Career
Understanding Morris traversal helps in optimizing tree traversal algorithms and is valuable for software engineers working on performance-critical applications or low-level system programming.
Progress0 / 4 steps
1
Create the binary tree structure and nodes
Define a struct called Node with fields Val int, Left *Node, and Right *Node. Then create a binary tree with root node value 1, root's left child value 2, root's right child value 3, left child's left child value 4, and left child's right child value 5.
DSA Go
Hint
Start by defining the Node struct with the three fields. Then create the root node and assign its left and right children as described.
2
Add a variable to hold the current node during traversal
Inside the main function, create a variable called current and set it equal to root. This will be used to traverse the tree.
DSA Go
Hint
Just assign current to root inside main.
3
Implement Morris inorder traversal logic
Write a for loop that runs while current != nil. Inside the loop, if current.Left is nil, print current.Val followed by a space and move current to current.Right. Otherwise, find the inorder predecessor of current by moving to current.Left and then repeatedly to the right child until the right child is nil or current. If the predecessor's right child is nil, set it to current and move current to current.Left. If the predecessor's right child is current, set it back to nil, print current.Val followed by a space, and move current to current.Right.
DSA Go
Hint
Use a for loop with current != nil. Inside, check if current.Left is nil. If yes, print and move right. Otherwise, find the predecessor and create or remove the thread accordingly.
4
Print the inorder traversal result
Add a newline print statement after the Morris traversal loop to move the cursor to the next line.
DSA Go
Hint
After the loop finishes printing all node values with spaces, print a newline using fmt.Println() to end the output cleanly.
Practice
(1/5)
1. What is the main advantage of Morris Traversal for inorder tree traversal compared to the traditional recursive or stack-based methods?
easy
A. It is faster than all other traversal methods
B. It requires the tree to be balanced
C. It only works on binary search trees
D. It uses no extra space for stack or recursion
Solution
Step 1: Understand Morris Traversal space usage
Morris Traversal modifies the tree temporarily to avoid using stack or recursion, so it uses O(1) extra space.
Step 2: Compare with other methods
Traditional inorder traversal uses recursion or stack which requires O(h) space, where h is tree height.
Final Answer:
It uses no extra space for stack or recursion -> Option D
Quick Check:
Morris Traversal = O(1) space [OK]
Hint: Morris Traversal saves space by threading nodes [OK]
Common Mistakes:
Thinking it is faster than all methods
Assuming it only works on BSTs
Believing it needs balanced trees
2. Which of the following Go code snippets correctly initializes a pointer to the current node for Morris inorder traversal?
easy
A. current := root
B. var current *Node = nil
C. current := &root
D. current := root.left
Solution
Step 1: Understand pointer initialization
For traversal, current should start at root node, so current := root is correct.
Step 2: Check other options
var current *Node = nil sets current to nil, which stops traversal immediately. current := &root takes address of root pointer, incorrect. current := root.left starts at left child, skipping root.
Final Answer:
current := root -> Option A
Quick Check:
Start traversal at root = current := root [OK]
Hint: Start traversal pointer at root node [OK]
Common Mistakes:
Initializing current as nil
Taking address of root pointer
Starting at root.left instead of root
3. Given the following binary tree and Morris inorder traversal code, what is the printed output?
2
/ \
1 3
func morrisInorder(root *Node) {
current := root
for current != nil {
if current.Left == nil {
fmt.Print(current.Val, " ")
current = current.Right
} else {
pre := current.Left
for pre.Right != nil && pre.Right != current {
pre = pre.Right
}
if pre.Right == nil {
pre.Right = current
current = current.Left
} else {
pre.Right = nil
fmt.Print(current.Val, " ")
current = current.Right
}
}
}
}
medium
A. 2 1 3
B. 1 2 3
C. 3 2 1
D. 1 3 2
Solution
Step 1: Understand inorder traversal order
Inorder traversal visits left subtree, root, then right subtree. For tree 2 with left 1 and right 3, order is 1 2 3.
Step 2: Trace Morris traversal output
Morris traversal prints nodes in inorder without stack. The code prints 1, then 2, then 3 with spaces.
Final Answer:
1 2 3 -> Option B
Quick Check:
Inorder of given tree = 1 2 3 [OK]
Hint: Inorder prints left-root-right sequence [OK]
Common Mistakes:
Confusing preorder or postorder output
Misreading the tree structure
Ignoring Morris threading logic
4. Consider this snippet of Morris inorder traversal in Go. What is the bug that causes an infinite loop?
current := root
for current != nil {
if current.Left != nil {
pre := current.Left
for pre.Right != nil {
pre = pre.Right
}
pre.Right = current
current = current.Left
} else {
fmt.Print(current.Val, " ")
current = current.Right
}
}
medium
A. Printing node values before traversal
B. Incorrect initialization of current pointer
C. Missing check if pre.Right == current before setting pre.Right = current
D. Not updating current to current.Left in else block
Solution
Step 1: Analyze inner loop for threading
The inner loop finds rightmost node of left subtree. Without checking if pre.Right == current, it keeps looping infinitely.
Correct Morris traversal checks if pre.Right is nil or points to current to avoid infinite loop. Missing this causes infinite loop.
Final Answer:
Missing check if pre.Right == current before setting pre.Right = current -> Option C
Quick Check:
Check pre.Right == current to avoid loops [OK]
Hint: Always check if thread already exists before linking [OK]
Common Mistakes:
Skipping pre.Right == current check
Wrong pointer updates
Printing too early
5. You want to modify Morris inorder traversal to count the number of nodes in a binary tree without using extra space or recursion. Which change correctly achieves this?
hard
A. Add a counter variable and increment it each time you print a node's value during traversal
B. Increment counter only when creating a thread (pre.Right = current)
C. Increment counter only when removing a thread (pre.Right = nil)
D. Increment counter only when current.Left is nil
Solution
Step 1: Identify when nodes are visited in Morris traversal
Nodes are printed exactly once: when current.Left == nil or when removing the thread (pre.Right != nil).
Step 2: Choose correct increment point for counting
Incrementing the counter each time a node's value is printed ensures every node is counted exactly once.
Final Answer:
Add a counter variable and increment it each time you print a node's value during traversal -> Option A
Quick Check:
Increment on every print operation [OK]
Hint: Count nodes when printing each node [OK]
Common Mistakes:
Incrementing only when current.Left is nil (misses nodes with left subtrees)
Incrementing when creating threads (counts only non-leaf nodes)
Incrementing when removing threads (counts only non-leaf nodes)
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.