Skip to content

Commit 69676c2

Browse files
committed
Add Morris Traversal algorithm for inorder tree traversal
- Implements Morris Traversal (threaded binary tree) algorithm - O(1) space complexity inorder traversal without recursion/stack - Includes comprehensive documentation and examples - Wikipedia reference: https://en.wikipedia.org/wiki/Threaded_binary_tree#Morris_traversal
1 parent 08d8c6b commit 69676c2

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

Trees/MorrisTraversal.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* Morris Traversal (Inorder Traversal without recursion or stack)
3+
* Wikipedia: https://en.wikipedia.org/wiki/Threaded_binary_tree#Morris_traversal
4+
*
5+
* WHAT IS MORRIS TRAVERSAL?
6+
* Morris Traversal is a clever technique to traverse a binary tree in inorder
7+
* (Left → Root → Right) using O(1) extra space - meaning it doesn't need recursion
8+
* or an explicit stack like traditional methods.
9+
*
10+
* HOW DOES IT WORK?
11+
* The algorithm temporarily modifies the tree by creating "threads" (temporary links)
12+
* that help us navigate back to parent nodes without using extra memory.
13+
* Think of it like leaving breadcrumbs to find your way back!
14+
*
15+
* KEY CONCEPT - INORDER PREDECESSOR:
16+
* For any node, its inorder predecessor is the rightmost node in its left subtree.
17+
* This is the node that comes just before it in inorder traversal.
18+
*
19+
* ALGORITHM STEPS:
20+
* 1. Start at root, move current pointer through the tree
21+
* 2. If current node has no left child: visit it, move right
22+
* 3. If current node has left child:
23+
* a. Find the inorder predecessor (rightmost in left subtree)
24+
* b. If predecessor's right is null: create thread, go left
25+
* c. If predecessor's right points to current: remove thread, visit current, go right
26+
*
27+
* Example Tree:
28+
* 7
29+
* / \
30+
* 5 8
31+
* / \
32+
* 3 6
33+
* \
34+
* 9
35+
*
36+
* Traversal order: 3 → 5 → 6 → 9 → 7 → 8
37+
*
38+
* TIME COMPLEXITY: O(n) - each edge is traversed at most twice
39+
* SPACE COMPLEXITY: O(1) - no extra space except for result array
40+
*/
41+
42+
class TreeNode {
43+
constructor(val, left = null, right = null) {
44+
this.val = val;
45+
this.left = left;
46+
this.right = right;
47+
}
48+
}
49+
50+
function morrisTraversal(root) {
51+
const result = []; // Array to store the inorder traversal result
52+
let curr = root; // Current node we're processing
53+
54+
// Continue until we've processed all nodes
55+
while (curr) {
56+
57+
// CASE 1: Current node has no left child
58+
// This means we can safely visit this node (no left subtree to process first)
59+
if (!curr.left) {
60+
result.push(curr.val); // Visit the current node
61+
curr = curr.right; // Move to right subtree
62+
}
63+
64+
// CASE 2: Current node has a left child
65+
// We need to find a way to come back to this node after processing left subtree
66+
else {
67+
68+
// STEP 1: Find the inorder predecessor of current node
69+
// (Rightmost node in the left subtree)
70+
let pred = curr.left;
71+
72+
// Keep going right until we find the rightmost node
73+
// BUT stop if we find a node that already points back to curr (existing thread)
74+
while (pred.right && pred.right !== curr) {
75+
pred = pred.right;
76+
}
77+
78+
// STEP 2a: If predecessor's right is null, we need to create a thread
79+
// This thread will help us return to current node later
80+
if (!pred.right) {
81+
// Create the thread: make predecessor point to current node
82+
pred.right = curr;
83+
84+
// Now go left to process the left subtree first
85+
curr = curr.left;
86+
}
87+
88+
// STEP 2b: If predecessor's right already points to current node
89+
// This means we've already processed the left subtree and are back via the thread
90+
else {
91+
// Remove the thread (restore original tree structure)
92+
pred.right = null;
93+
94+
// Now we can safely visit the current node
95+
result.push(curr.val);
96+
97+
// Move to right subtree
98+
curr = curr.right;
99+
}
100+
}
101+
}
102+
103+
return result;
104+
}
105+
106+
module.exports = { TreeNode, morrisTraversal };

0 commit comments

Comments
 (0)