-
-
Notifications
You must be signed in to change notification settings - Fork 50.5k
build binary-tree using traversals #13768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
1ec0ff0
a7bb97c
5702627
dff30d0
ee149d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| """ | ||
| Build a binary tree from preorder + inorder or postorder + inorder traversals. | ||
|
|
||
| This module provides two main functions: | ||
| - build_tree_from_preorder_and_inorder() | ||
| - build_tree_from_postorder_and_inorder() | ||
|
|
||
| Each builds a binary tree represented by Node objects. | ||
|
|
||
| References: | ||
| - https://en.wikipedia.org/wiki/Binary_tree | ||
| - https://en.wikipedia.org/wiki/Tree_traversal | ||
| """ | ||
|
|
||
| from typing import Dict, List, Optional | ||
|
Check failure on line 15 in data_structures/binary_tree/build_tree_from_traversal.py
|
||
|
|
||
|
|
||
| class Node: | ||
| """ | ||
| A class representing a node in a binary tree. | ||
|
|
||
| Attributes: | ||
| data (int): The value of the node. | ||
| left (Optional[Node]): Pointer to the left child. | ||
| right (Optional[Node]): Pointer to the right child. | ||
| """ | ||
|
|
||
| def __init__(self, data: int) -> None: | ||
| self.data = data | ||
| self.left: Optional[Node] = None | ||
| self.right: Optional[Node] = None | ||
|
|
||
|
|
||
| def inorder_traversal(root: Optional[Node]) -> List[int]: | ||
|
Check failure on line 34 in data_structures/binary_tree/build_tree_from_traversal.py
|
||
| """ | ||
| Return the inorder traversal of a binary tree as a list. | ||
|
|
||
| >>> root = Node(3) | ||
| >>> root.left = Node(2) | ||
| >>> root.right = Node(4) | ||
| >>> inorder_traversal(root) | ||
| [2, 3, 4] | ||
| """ | ||
| if root is None: | ||
| return [] | ||
| return inorder_traversal(root.left) + [root.data] + inorder_traversal(root.right) | ||
|
|
||
|
|
||
| def _build_tree_from_preorder( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
| preorder: List[int], | ||
| pre_start: int, | ||
| pre_end: int, | ||
| inorder_seq: List[int], | ||
| in_start: int, | ||
| in_end: int, | ||
| inorder_map: Dict[int, int], | ||
| ) -> Optional[Node]: | ||
| """Helper function for building a tree recursively from preorder + inorder.""" | ||
| if pre_start > pre_end or in_start > in_end: | ||
| return None | ||
|
|
||
| root_value = preorder[pre_start] | ||
| root = Node(root_value) | ||
| in_root_index = inorder_map[root_value] | ||
| left_subtree_size = in_root_index - in_start | ||
|
|
||
| root.left = _build_tree_from_preorder( | ||
| preorder, | ||
| pre_start + 1, | ||
| pre_start + left_subtree_size, | ||
| inorder_seq, | ||
| in_start, | ||
| in_root_index - 1, | ||
| inorder_map, | ||
| ) | ||
| root.right = _build_tree_from_preorder( | ||
| preorder, | ||
| pre_start + left_subtree_size + 1, | ||
| pre_end, | ||
| inorder_seq, | ||
| in_root_index + 1, | ||
| in_end, | ||
| inorder_map, | ||
| ) | ||
| return root | ||
|
|
||
|
|
||
| def build_tree_from_preorder_and_inorder( | ||
| inorder_seq: List[int], preorder_seq: List[int] | ||
| ) -> Optional[Node]: | ||
| """ | ||
| Build a binary tree from preorder and inorder traversals. | ||
|
|
||
| Args: | ||
| inorder_seq: The inorder traversal sequence. | ||
| preorder_seq: The preorder traversal sequence. | ||
|
|
||
| Returns: | ||
| Root node of the reconstructed binary tree. | ||
|
|
||
| >>> inorder_seq = [1, 2, 3, 4, 5] | ||
| >>> preorder_seq = [3, 2, 1, 4, 5] | ||
| >>> root = build_tree_from_preorder_and_inorder(inorder_seq, preorder_seq) | ||
| >>> inorder_traversal(root) | ||
| [1, 2, 3, 4, 5] | ||
| """ | ||
| inorder_map = {value: i for i, value in enumerate(inorder_seq)} | ||
| return _build_tree_from_preorder( | ||
| preorder_seq, | ||
| 0, | ||
| len(preorder_seq) - 1, | ||
| inorder_seq, | ||
| 0, | ||
| len(inorder_seq) - 1, | ||
| inorder_map, | ||
| ) | ||
|
|
||
|
|
||
| def _build_tree_from_postorder( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
| postorder: List[int], | ||
| post_start: int, | ||
| post_end: int, | ||
| inorder_seq: List[int], | ||
| in_start: int, | ||
| in_end: int, | ||
| inorder_map: Dict[int, int], | ||
| ) -> Optional[Node]: | ||
| """Helper function for building a tree recursively from postorder + inorder.""" | ||
| if post_start > post_end or in_start > in_end: | ||
| return None | ||
|
|
||
| root_value = postorder[post_end] | ||
| root = Node(root_value) | ||
| in_root_index = inorder_map[root_value] | ||
| left_subtree_size = in_root_index - in_start | ||
|
|
||
| root.left = _build_tree_from_postorder( | ||
| postorder, | ||
| post_start, | ||
| post_start + left_subtree_size - 1, | ||
| inorder_seq, | ||
| in_start, | ||
| in_root_index - 1, | ||
| inorder_map, | ||
| ) | ||
| root.right = _build_tree_from_postorder( | ||
| postorder, | ||
| post_start + left_subtree_size, | ||
| post_end - 1, | ||
| inorder_seq, | ||
| in_root_index + 1, | ||
| in_end, | ||
| inorder_map, | ||
| ) | ||
| return root | ||
|
|
||
|
|
||
| def build_tree_from_postorder_and_inorder( | ||
| inorder_seq: List[int], postorder_seq: List[int] | ||
| ) -> Optional[Node]: | ||
| """ | ||
| Build a binary tree from postorder and inorder traversals. | ||
|
|
||
| Args: | ||
| inorder_seq: The inorder traversal sequence. | ||
| postorder_seq: The postorder traversal sequence. | ||
|
|
||
| Returns: | ||
| Root node of the reconstructed binary tree. | ||
|
|
||
| >>> inorder_seq = [1, 2, 3, 4, 5] | ||
| >>> postorder_seq = [1, 2, 5, 4, 3] | ||
| >>> root = build_tree_from_postorder_and_inorder(inorder_seq, postorder_seq) | ||
| >>> inorder_traversal(root) | ||
| [1, 2, 3, 4, 5] | ||
| """ | ||
| inorder_map = {value: i for i, value in enumerate(inorder_seq)} | ||
| return _build_tree_from_postorder( | ||
| postorder_seq, | ||
| 0, | ||
| len(postorder_seq) - 1, | ||
| inorder_seq, | ||
| 0, | ||
| len(inorder_seq) - 1, | ||
| inorder_map, | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| # Example usage for manual verification (not part of algorithmic test) | ||
| inorder_seq = [1, 2, 3, 4, 5] | ||
| preorder_seq = [3, 2, 1, 4, 5] | ||
| postorder_seq = [1, 2, 5, 4, 3] | ||
|
|
||
| root_pre = build_tree_from_preorder_and_inorder(inorder_seq, preorder_seq) | ||
| print("Inorder (from Preorder+Inorder):", inorder_traversal(root_pre)) | ||
|
|
||
| root_post = build_tree_from_postorder_and_inorder(inorder_seq, postorder_seq) | ||
| print("Inorder (from Postorder+Inorder):", inorder_traversal(root_post)) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As there is no test file in this pull request nor any test function or class in the file
data_structures/binary_tree/build_tree_from_traversal.py, please provide doctest for the function_build_tree_from_preorder