Skip to content

Commit e4a9f54

Browse files
committed
feat: Implemented Morris Inorder traversal for Binary tree
1 parent 9a572de commit e4a9f54

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"""
2+
Problem Statement: Given a binary perform an inorder traversal using Morris Inorder
3+
traversal algorithm. (Iterative version of Inorder traversal of tree)
4+
5+
https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/
6+
"""
7+
8+
9+
class TreeNode:
10+
"""
11+
Class representing a node in a binary tree.
12+
13+
Attributes:
14+
-----------
15+
value : int
16+
The value stored at the node.
17+
left : TreeNode
18+
Pointer to the left child node (default is None).
19+
right : TreeNode
20+
Pointer to the right child node (default is None).
21+
"""
22+
23+
def __init__(self, value: int) -> None:
24+
self.value = value
25+
self.left: TreeNode | None = None
26+
self.right: TreeNode | None = None
27+
28+
29+
class BinaryTree:
30+
"""
31+
Class representing a binary tree.
32+
33+
Methods:
34+
--------
35+
insert(value: int) -> None:
36+
Insert a value into the binary tree following binary search tree (BST) rules.
37+
38+
morris_inorder_traversal() -> List[int]:
39+
Perform inorder traversal and return list of node values.
40+
41+
42+
>>> bt = BinaryTree()
43+
>>> bt.insert(9)
44+
>>> bt.insert(6)
45+
>>> bt.insert(10)
46+
>>> bt.insert(3)
47+
>>> bt.insert(7)
48+
>>> bt.insert(12)
49+
>>> bt.insert(2)
50+
>>> bt.insert(5)
51+
>>> bt.insert(4)
52+
>>> bt.morris_inorder_traversal()
53+
[2, 3, 4, 5, 6, 7, 9, 10, 12]
54+
55+
"""
56+
57+
def __init__(self) -> None:
58+
self.root: TreeNode | None = None
59+
60+
def insert(self, value: int) -> None:
61+
"""
62+
Insert a value into the binary tree.
63+
64+
Parameters:
65+
-----------
66+
value : int
67+
The value to be inserted into the binary tree.
68+
"""
69+
if self.root is None:
70+
self.root = TreeNode(value)
71+
else:
72+
self._insert_recursive(self.root, value)
73+
74+
def _insert_recursive(self, node: TreeNode, value: int) -> None:
75+
"""
76+
Helper function to insert a value recursively into the tree.
77+
78+
Parameters:
79+
-----------
80+
node : TreeNode
81+
The current node in the binary tree.
82+
value : int
83+
The value to be inserted.
84+
"""
85+
if value < node.value:
86+
if node.left is None:
87+
node.left = TreeNode(value)
88+
else:
89+
self._insert_recursive(node.left, value)
90+
elif node.right is None:
91+
node.right = TreeNode(value)
92+
else:
93+
self._insert_recursive(node.right, value)
94+
95+
def _predecessor(self, node: TreeNode) -> TreeNode:
96+
"""
97+
Helper Function to return predecessor of the given node in a binary tree
98+
99+
Parameters:
100+
-----------
101+
node : TreeNode
102+
A node in the binary tree.
103+
104+
Returns:
105+
--------
106+
TreeNode:
107+
The predecessor of the node passed in the parameter
108+
"""
109+
temp_node = node.left
110+
while temp_node and temp_node.right and temp_node.right != node:
111+
temp_node = temp_node.right
112+
assert temp_node is not None, "Predecessor should not be None"
113+
return temp_node
114+
115+
def morris_inorder_traversal(self) -> list[int]:
116+
"""
117+
Function for inorder traversal using morris inorder traversal.
118+
119+
Algorithm :
120+
------------
121+
First set current node as root node.
122+
123+
while current node is not empty
124+
If the current node has no left child.
125+
print the current node.
126+
point the current node to its right child
127+
128+
else.
129+
find predecssor node of the current node.
130+
if predecessor has no right child,
131+
make the current node as the right child of the predecessor node.
132+
point current node to its left child.
133+
else,
134+
remove the link of the right child of predecessor node.
135+
print the current node
136+
point the current node to its right child.
137+
138+
Returns:
139+
--------
140+
List[int]:
141+
A list of integers representing the inorder traversal.
142+
143+
144+
145+
"""
146+
inorder_traversal = []
147+
current_node = self.root
148+
149+
while current_node:
150+
if current_node.left is None:
151+
inorder_traversal.append(current_node.value)
152+
current_node = current_node.right
153+
else:
154+
predecessor_node = self._predecessor(current_node)
155+
if predecessor_node.right is None:
156+
predecessor_node.right = current_node
157+
current_node = current_node.left
158+
else:
159+
predecessor_node.right = None
160+
inorder_traversal.append(current_node.value)
161+
current_node = current_node.right
162+
return inorder_traversal
163+
164+
165+
if __name__ == "__main__":
166+
import doctest
167+
168+
doctest.testmod()

0 commit comments

Comments
 (0)