Skip to content

Commit 5702627

Browse files
committed
build tree from traversals new
1 parent a7bb97c commit 5702627

File tree

1 file changed

+133
-77
lines changed

1 file changed

+133
-77
lines changed
Lines changed: 133 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,199 @@
1-
# Binary Tree Node class
1+
"""
2+
Build a binary tree from preorder + inorder or postorder + inorder traversals.
3+
4+
This module provides two main functions:
5+
- build_tree_from_preorder_and_inorder()
6+
- build_tree_from_postorder_and_inorder()
7+
8+
Each builds a binary tree represented by Node objects.
9+
10+
References:
11+
- https://en.wikipedia.org/wiki/Binary_tree
12+
- https://en.wikipedia.org/wiki/Tree_traversal
13+
"""
14+
15+
from typing import Dict, List, Optional
16+
17+
218
class Node:
3-
def __init__(self, data):
4-
self.data = data
5-
self.left = None
6-
self.right = None
19+
"""
20+
A class representing a node in a binary tree.
721
22+
Attributes:
23+
data (int): The value of the node.
24+
left (Optional[Node]): Pointer to the left child.
25+
right (Optional[Node]): Pointer to the right child.
26+
"""
827

9-
# Normal inorder traversal
10-
def inorder(root, out):
11-
"""Perform inorder traversal and append values to 'out' list."""
12-
if root is None:
13-
return
14-
inorder(root.left, out)
15-
out.append(root.data)
16-
inorder(root.right, out)
28+
def __init__(self, data: int) -> None:
29+
self.data = data
30+
self.left: Optional[Node] = None
31+
self.right: Optional[Node] = None
1732

1833

19-
# === Build tree using PREORDER + INORDER ===
20-
def build_tree_from_pre(
21-
preorder, pre_start, pre_end, inorder_seq, in_start, in_end, in_map
22-
):
23-
"""Recursive helper to build tree from preorder and inorder traversal."""
34+
def inorder_traversal(root: Optional[Node]) -> List[int]:
35+
"""
36+
Return the inorder traversal of a binary tree as a list.
37+
38+
>>> root = Node(3)
39+
>>> root.left = Node(2)
40+
>>> root.right = Node(4)
41+
>>> inorder_traversal(root)
42+
[2, 3, 4]
43+
"""
44+
if root is None:
45+
return []
46+
return inorder_traversal(root.left) + [root.data] + inorder_traversal(root.right)
47+
48+
49+
def _build_tree_from_preorder(
50+
preorder: List[int],
51+
pre_start: int,
52+
pre_end: int,
53+
inorder_seq: List[int],
54+
in_start: int,
55+
in_end: int,
56+
inorder_map: Dict[int, int],
57+
) -> Optional[Node]:
58+
"""Helper function for building a tree recursively from preorder + inorder."""
2459
if pre_start > pre_end or in_start > in_end:
2560
return None
2661

27-
# Root is the first element in current preorder segment
28-
root_val = preorder[pre_start]
29-
root = Node(root_val)
30-
31-
# Find the root index in inorder traversal
32-
in_root_index = in_map[root_val]
33-
nums_left = in_root_index - in_start
62+
root_value = preorder[pre_start]
63+
root = Node(root_value)
64+
in_root_index = inorder_map[root_value]
65+
left_subtree_size = in_root_index - in_start
3466

35-
# Recursively build left and right subtrees
36-
root.left = build_tree_from_pre(
67+
root.left = _build_tree_from_preorder(
3768
preorder,
3869
pre_start + 1,
39-
pre_start + nums_left,
70+
pre_start + left_subtree_size,
4071
inorder_seq,
4172
in_start,
4273
in_root_index - 1,
43-
in_map,
74+
inorder_map,
4475
)
45-
46-
root.right = build_tree_from_pre(
76+
root.right = _build_tree_from_preorder(
4777
preorder,
48-
pre_start + nums_left + 1,
78+
pre_start + left_subtree_size + 1,
4979
pre_end,
5080
inorder_seq,
5181
in_root_index + 1,
5282
in_end,
53-
in_map,
83+
inorder_map,
5484
)
55-
5685
return root
5786

5887

59-
def build_tree_pre(inorder_seq, preorder_seq):
60-
"""Wrapper function for building tree from preorder + inorder."""
61-
in_map = {val: i for i, val in enumerate(inorder_seq)}
62-
return build_tree_from_pre(
88+
def build_tree_from_preorder_and_inorder(
89+
inorder_seq: List[int], preorder_seq: List[int]
90+
) -> Optional[Node]:
91+
"""
92+
Build a binary tree from preorder and inorder traversals.
93+
94+
Args:
95+
inorder_seq: The inorder traversal sequence.
96+
preorder_seq: The preorder traversal sequence.
97+
98+
Returns:
99+
Root node of the reconstructed binary tree.
100+
101+
>>> inorder_seq = [1, 2, 3, 4, 5]
102+
>>> preorder_seq = [3, 2, 1, 4, 5]
103+
>>> root = build_tree_from_preorder_and_inorder(inorder_seq, preorder_seq)
104+
>>> inorder_traversal(root)
105+
[1, 2, 3, 4, 5]
106+
"""
107+
inorder_map = {value: i for i, value in enumerate(inorder_seq)}
108+
return _build_tree_from_preorder(
63109
preorder_seq,
64110
0,
65111
len(preorder_seq) - 1,
66112
inorder_seq,
67113
0,
68114
len(inorder_seq) - 1,
69-
in_map,
115+
inorder_map,
70116
)
71117

72118

73-
# === Build tree using POSTORDER + INORDER ===
74-
def build_tree_from_post(
75-
postorder, post_start, post_end, inorder_seq, in_start, in_end, in_map
76-
):
77-
"""Recursive helper to build tree from postorder and inorder traversal."""
119+
def _build_tree_from_postorder(
120+
postorder: List[int],
121+
post_start: int,
122+
post_end: int,
123+
inorder_seq: List[int],
124+
in_start: int,
125+
in_end: int,
126+
inorder_map: Dict[int, int],
127+
) -> Optional[Node]:
128+
"""Helper function for building a tree recursively from postorder + inorder."""
78129
if post_start > post_end or in_start > in_end:
79130
return None
80131

81-
# Root is the last element in current postorder segment
82-
root_val = postorder[post_end]
83-
root = Node(root_val)
84-
85-
# Find the root index in inorder traversal
86-
in_root_index = in_map[root_val]
87-
nums_left = in_root_index - in_start
132+
root_value = postorder[post_end]
133+
root = Node(root_value)
134+
in_root_index = inorder_map[root_value]
135+
left_subtree_size = in_root_index - in_start
88136

89-
# Recursively build left and right subtrees
90-
root.left = build_tree_from_post(
137+
root.left = _build_tree_from_postorder(
91138
postorder,
92139
post_start,
93-
post_start + nums_left - 1,
140+
post_start + left_subtree_size - 1,
94141
inorder_seq,
95142
in_start,
96143
in_root_index - 1,
97-
in_map,
144+
inorder_map,
98145
)
99-
100-
root.right = build_tree_from_post(
146+
root.right = _build_tree_from_postorder(
101147
postorder,
102-
post_start + nums_left,
148+
post_start + left_subtree_size,
103149
post_end - 1,
104150
inorder_seq,
105151
in_root_index + 1,
106152
in_end,
107-
in_map,
153+
inorder_map,
108154
)
109-
110155
return root
111156

112157

113-
def build_tree_post(inorder_seq, postorder_seq):
114-
"""Wrapper function for building tree from postorder + inorder."""
115-
in_map = {val: i for i, val in enumerate(inorder_seq)}
116-
return build_tree_from_post(
158+
def build_tree_from_postorder_and_inorder(
159+
inorder_seq: List[int], postorder_seq: List[int]
160+
) -> Optional[Node]:
161+
"""
162+
Build a binary tree from postorder and inorder traversals.
163+
164+
Args:
165+
inorder_seq: The inorder traversal sequence.
166+
postorder_seq: The postorder traversal sequence.
167+
168+
Returns:
169+
Root node of the reconstructed binary tree.
170+
171+
>>> inorder_seq = [1, 2, 3, 4, 5]
172+
>>> postorder_seq = [1, 2, 5, 4, 3]
173+
>>> root = build_tree_from_postorder_and_inorder(inorder_seq, postorder_seq)
174+
>>> inorder_traversal(root)
175+
[1, 2, 3, 4, 5]
176+
"""
177+
inorder_map = {value: i for i, value in enumerate(inorder_seq)}
178+
return _build_tree_from_postorder(
117179
postorder_seq,
118180
0,
119181
len(postorder_seq) - 1,
120182
inorder_seq,
121183
0,
122184
len(inorder_seq) - 1,
123-
in_map,
185+
inorder_map,
124186
)
125187

126188

127-
# === Example ===
128189
if __name__ == "__main__":
190+
# Example usage for manual verification (not part of algorithmic test)
129191
inorder_seq = [1, 2, 3, 4, 5]
130192
preorder_seq = [3, 2, 1, 4, 5]
131193
postorder_seq = [1, 2, 5, 4, 3]
132194

133-
print("=== Build BST from Preorder & Inorder ===")
134-
tree_pre = build_tree_pre(inorder_seq, preorder_seq)
135-
out = []
136-
inorder(tree_pre, out)
137-
print("Inorder:", *out)
138-
139-
print("=== Build BST from Postorder & Inorder ===")
140-
tree_post = build_tree_post(inorder_seq, postorder_seq)
141-
out = []
142-
inorder(tree_post, out)
143-
print("Inorder:", *out)
195+
root_pre = build_tree_from_preorder_and_inorder(inorder_seq, preorder_seq)
196+
print("Inorder (from Preorder+Inorder):", inorder_traversal(root_pre))
197+
198+
root_post = build_tree_from_postorder_and_inorder(inorder_seq, postorder_seq)
199+
print("Inorder (from Postorder+Inorder):", inorder_traversal(root_post))

0 commit comments

Comments
 (0)