DEV Community

Jaspreet singh
Jaspreet singh

Posted on

Morris Pre Order Traversal

Problem Statement

Given the root of a binary tree, return its preorder traversal.

The challenge is to perform the traversal:

Without Recursion

Without Stack

O(1) Extra Space
Enter fullscreen mode Exit fullscreen mode

Brute Force Intuition

In an interview, you can explain it like this:

Perform a normal recursive preorder traversal.

Traversal order:

Root

↓

Left

↓

Right
Enter fullscreen mode Exit fullscreen mode

Recursion naturally remembers the parent nodes.

Complexity

  • Time Complexity: O(N)
  • Space Complexity: O(H)

Better Approach

Use an explicit stack.

Visit:

Root

↓

Left

↓

Right
Enter fullscreen mode Exit fullscreen mode

Complexity

  • Time Complexity: O(N)
  • Space Complexity: O(H)

Moving Towards the Optimal Approach

Can we perform preorder traversal without:

Recursion

OR

Stack?
Enter fullscreen mode Exit fullscreen mode

Yes.

Instead of using recursion,

temporarily connect the inorder predecessor back to the current node.

This temporary connection is called a:

Thread
Enter fullscreen mode Exit fullscreen mode

Unlike Morris Inorder,

here we visit the node before moving to the left subtree.


Pattern Recognition

Whenever you see:

  • Binary Tree Traversal
  • O(1) Extra Space
  • No Stack
  • No Recursion

Think:

Morris Traversal


Key Observation

For every node:

Case 1

No Left Child
Enter fullscreen mode Exit fullscreen mode

Visit it immediately.

Move:

Right
Enter fullscreen mode Exit fullscreen mode

Case 2

Has Left Child
Enter fullscreen mode Exit fullscreen mode

Find its:

Inorder Predecessor
Enter fullscreen mode Exit fullscreen mode

(the rightmost node of the left subtree)

If predecessor's right is:

NULL
Enter fullscreen mode Exit fullscreen mode

Visit current node.

Create a temporary thread.

Predecessor

↓

Current
Enter fullscreen mode Exit fullscreen mode

Move:

Left
Enter fullscreen mode Exit fullscreen mode

If predecessor already points to current,

remove the thread,

move to the right subtree.

Notice:

Unlike Morris Inorder,

we do not visit the node while removing the thread.


Visualization

Original Tree

        4
       / \
      2   5
     / \
    1   3
Enter fullscreen mode Exit fullscreen mode

Temporary Thread

3
 \
  4
Enter fullscreen mode Exit fullscreen mode

After returning,

the thread is removed,

restoring the original tree.


Optimal Java Solution

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {

        List<Integer> ans = new ArrayList<>();

        TreeNode curr = root;

        while (curr != null) {

            if (curr.left == null) {

                ans.add(curr.val);

                curr = curr.right;

            } else {

                TreeNode pred = curr.left;

                while (pred.right != null &&
                       pred.right != curr) {

                    pred = pred.right;
                }

                if (pred.right == null) {

                    ans.add(curr.val);

                    pred.right = curr;

                    curr = curr.left;

                } else {

                    pred.right = null;

                    curr = curr.right;
                }
            }
        }

        return ans;
    }
}
Enter fullscreen mode Exit fullscreen mode

Dry Run

Tree

        4
       / \
      2   5
     / \
    1   3
Enter fullscreen mode Exit fullscreen mode

Step 1

Current:

4
Enter fullscreen mode Exit fullscreen mode

Visit:

4
Enter fullscreen mode Exit fullscreen mode

Create thread:

3 → 4
Enter fullscreen mode Exit fullscreen mode

Move left.


Step 2

Current:

2
Enter fullscreen mode Exit fullscreen mode

Visit:

2
Enter fullscreen mode Exit fullscreen mode

Create thread:

1 → 2
Enter fullscreen mode Exit fullscreen mode

Move left.


Step 3

Current:

1
Enter fullscreen mode Exit fullscreen mode

No left child.

Visit:

1
Enter fullscreen mode Exit fullscreen mode

Move through thread.


Step 4

Back to:

2
Enter fullscreen mode Exit fullscreen mode

Remove thread.

Move right.

Visit:

3
Enter fullscreen mode Exit fullscreen mode

Return through thread.

Visit:

5
Enter fullscreen mode Exit fullscreen mode

Final Traversal

4

2

1

3

5
Enter fullscreen mode Exit fullscreen mode

Why Morris Preorder Works?

Instead of using recursion,

we temporarily connect:

Inorder Predecessor

↓

Current Node
Enter fullscreen mode Exit fullscreen mode

Since preorder visits the root first,

we process the node when creating the thread.

When we return,

the thread is removed,

and the original tree is restored.

Each edge is traversed at most twice.


Complexity Analysis

Metric Complexity
Time Complexity O(N)
Space Complexity O(1)

Interview One-Liner

Morris Preorder Traversal visits the node before creating a temporary thread to its inorder predecessor, achieving preorder traversal in O(1) extra space.


Pattern Learned

Need O(1) Space

↓

No Stack

↓

No Recursion

↓

Thread Binary Tree

↓

Visit Before Going Left
Enter fullscreen mode Exit fullscreen mode

Similar Problems

  • Morris Preorder Traversal
  • Morris Inorder Traversal
  • BST Iterator
  • Recover Binary Search Tree
  • Binary Tree Traversals

Memory Trick

Think:

Has Left Child?

↓

Find Predecessor

↓

Thread Exists?

↓

No

Visit Node

Create Thread

Go Left

----------------

Yes

Remove Thread

Go Right
Enter fullscreen mode Exit fullscreen mode

Mental Model

Current

↓

Visit

↓

Thread

↓

Left

↓

Back

↓

Right
Enter fullscreen mode Exit fullscreen mode

Whenever you hear:

"Preorder traversal without recursion or stack"

your brain should immediately think:

Morris Preorder Traversal

Top comments (0)