Skip to content

Commit bf0fe2e

Browse files
committed
fixes:#1806
1 parent 08d8c6b commit bf0fe2e

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

Sorts/MorrisTraversal.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Morris Traversal (Inorder)
3+
*
4+
* This algorithm performs an inorder traversal of a binary tree
5+
* without using recursion or a stack. Instead, it creates temporary
6+
* "threads" in the tree to traverse nodes in O(N) time and O(1) space.
7+
*
8+
* Time Complexity: O(N) (each edge visited at most twice)
9+
* Space Complexity: O(1)
10+
*
11+
* @param {TreeNode} root - Root node of the binary tree
12+
* @returns {number[]} - The inorder traversal as an array
13+
*/
14+
15+
export class TreeNode {
16+
constructor(val, left = null, right = null) {
17+
this.val = val
18+
this.left = left
19+
this.right = right
20+
}
21+
}
22+
23+
export function morrisTraversal(root) {
24+
const result = []
25+
let current = root
26+
27+
while (current !== null) {
28+
if (current.left === null) {
29+
// Case 1: No left child → visit current node
30+
result.push(current.val)
31+
current = current.right
32+
} else {
33+
// Case 2: Find inorder predecessor
34+
let predecessor = current.left
35+
while (predecessor.right !== null && predecessor.right !== current) {
36+
predecessor = predecessor.right
37+
}
38+
39+
if (predecessor.right === null) {
40+
// Create a temporary thread from predecessor to current
41+
predecessor.right = current
42+
current = current.left
43+
} else {
44+
// Thread already exists → remove it and visit current
45+
predecessor.right = null
46+
result.push(current.val)
47+
current = current.right
48+
}
49+
}
50+
}
51+
52+
return result
53+
}

Sorts/test/MorrisTraversal.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { morrisTraversal, TreeNode } from '../MorrisTraversal'
2+
3+
describe('morrisTraversal (Inorder)', () => {
4+
it('should return an empty array for an empty tree', () => {
5+
expect(morrisTraversal(null)).toEqual([])
6+
})
7+
8+
it('should return a single node when tree has only one node', () => {
9+
const root = new TreeNode(10)
10+
expect(morrisTraversal(root)).toEqual([10])
11+
})
12+
13+
it('should correctly traverse a simple balanced tree', () => {
14+
/**
15+
* 2
16+
* / \
17+
* 1 3
18+
*/
19+
const root = new TreeNode(2, new TreeNode(1), new TreeNode(3))
20+
expect(morrisTraversal(root)).toEqual([1, 2, 3])
21+
})
22+
23+
it('should handle a left-skewed tree', () => {
24+
/**
25+
* 3
26+
* /
27+
* 2
28+
* /
29+
*1
30+
*/
31+
const root = new TreeNode(3, new TreeNode(2, new TreeNode(1)))
32+
expect(morrisTraversal(root)).toEqual([1, 2, 3])
33+
})
34+
35+
it('should handle a right-skewed tree', () => {
36+
/**
37+
* 1
38+
* \
39+
* 2
40+
* \
41+
* 3
42+
*/
43+
const root = new TreeNode(1, null, new TreeNode(2, null, new TreeNode(3)))
44+
expect(morrisTraversal(root)).toEqual([1, 2, 3])
45+
})
46+
47+
it('should correctly traverse a larger tree', () => {
48+
/**
49+
* 4
50+
* / \
51+
* 2 5
52+
* / \
53+
* 1 3
54+
*/
55+
const root = new TreeNode(
56+
4,
57+
new TreeNode(2, new TreeNode(1), new TreeNode(3)),
58+
new TreeNode(5)
59+
)
60+
expect(morrisTraversal(root)).toEqual([1, 2, 3, 4, 5])
61+
})
62+
})

0 commit comments

Comments
 (0)