forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Binary Tree] Different views of binary tree added (TheAlgorithms#6965)
* Different views of binary tree added * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * mypy errors resolved * doc test for remaining functions * Flake8 comments resolved * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Example moved in if block * doctest cases added * Cases from if block removed * Update data_structures/binary_tree/diff_views_of_binary_tree.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update data_structures/binary_tree/diff_views_of_binary_tree.py Co-authored-by: Christian Clauss <cclauss@me.com> * PR Comments resolved * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * flake8 warning resolved * Changes revered * flake8 issue resolved * Put the diagrams just above the doctests * Update diff_views_of_binary_tree.py * Update diff_views_of_binary_tree.py * I love mypy * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
- Loading branch information
1 parent
0c7c5fa
commit 3448ae5
Showing
1 changed file
with
210 additions
and
0 deletions.
There are no files selected for viewing
210 changes: 210 additions & 0 deletions
210
data_structures/binary_tree/diff_views_of_binary_tree.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
r""" | ||
Problem: Given root of a binary tree, return the: | ||
1. binary-tree-right-side-view | ||
2. binary-tree-left-side-view | ||
3. binary-tree-top-side-view | ||
4. binary-tree-bottom-side-view | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from collections import defaultdict | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass | ||
class TreeNode: | ||
val: int | ||
left: TreeNode | None = None | ||
right: TreeNode | None = None | ||
|
||
|
||
def make_tree() -> TreeNode: | ||
""" | ||
>>> make_tree().val | ||
3 | ||
""" | ||
return TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7))) | ||
|
||
|
||
def binary_tree_right_side_view(root: TreeNode) -> list[int]: | ||
r""" | ||
Function returns the right side view of binary tree. | ||
3 <- 3 | ||
/ \ | ||
9 20 <- 20 | ||
/ \ | ||
15 7 <- 7 | ||
>>> binary_tree_right_side_view(make_tree()) | ||
[3, 20, 7] | ||
>>> binary_tree_right_side_view(None) | ||
[] | ||
""" | ||
|
||
def depth_first_search( | ||
root: TreeNode | None, depth: int, right_view: list[int] | ||
) -> None: | ||
""" | ||
A depth first search preorder traversal to append the values at | ||
right side of tree. | ||
""" | ||
if not root: | ||
return | ||
|
||
if depth == len(right_view): | ||
right_view.append(root.val) | ||
|
||
depth_first_search(root.right, depth + 1, right_view) | ||
depth_first_search(root.left, depth + 1, right_view) | ||
|
||
right_view: list = [] | ||
if not root: | ||
return right_view | ||
|
||
depth_first_search(root, 0, right_view) | ||
return right_view | ||
|
||
|
||
def binary_tree_left_side_view(root: TreeNode) -> list[int]: | ||
r""" | ||
Function returns the left side view of binary tree. | ||
3 -> 3 | ||
/ \ | ||
9 -> 9 20 | ||
/ \ | ||
15 -> 15 7 | ||
>>> binary_tree_left_side_view(make_tree()) | ||
[3, 9, 15] | ||
>>> binary_tree_left_side_view(None) | ||
[] | ||
""" | ||
|
||
def depth_first_search( | ||
root: TreeNode | None, depth: int, left_view: list[int] | ||
) -> None: | ||
""" | ||
A depth first search preorder traversal to append the values | ||
at left side of tree. | ||
""" | ||
if not root: | ||
return | ||
|
||
if depth == len(left_view): | ||
left_view.append(root.val) | ||
|
||
depth_first_search(root.left, depth + 1, left_view) | ||
depth_first_search(root.right, depth + 1, left_view) | ||
|
||
left_view: list = [] | ||
if not root: | ||
return left_view | ||
|
||
depth_first_search(root, 0, left_view) | ||
return left_view | ||
|
||
|
||
def binary_tree_top_side_view(root: TreeNode) -> list[int]: | ||
r""" | ||
Function returns the top side view of binary tree. | ||
9 3 20 7 | ||
⬇ ⬇ ⬇ ⬇ | ||
3 | ||
/ \ | ||
9 20 | ||
/ \ | ||
15 7 | ||
>>> binary_tree_top_side_view(make_tree()) | ||
[9, 3, 20, 7] | ||
>>> binary_tree_top_side_view(None) | ||
[] | ||
""" | ||
|
||
def breadth_first_search(root: TreeNode, top_view: list[int]) -> None: | ||
""" | ||
A breadth first search traversal with defaultdict ds to append | ||
the values of tree from top view | ||
""" | ||
queue = [(root, 0)] | ||
lookup = defaultdict(list) | ||
|
||
while queue: | ||
first = queue.pop(0) | ||
node, hd = first | ||
|
||
lookup[hd].append(node.val) | ||
|
||
if node.left: | ||
queue.append((node.left, hd - 1)) | ||
if node.right: | ||
queue.append((node.right, hd + 1)) | ||
|
||
for pair in sorted(lookup.items(), key=lambda each: each[0]): | ||
top_view.append(pair[1][0]) | ||
|
||
top_view: list = [] | ||
if not root: | ||
return top_view | ||
|
||
breadth_first_search(root, top_view) | ||
return top_view | ||
|
||
|
||
def binary_tree_bottom_side_view(root: TreeNode) -> list[int]: | ||
r""" | ||
Function returns the bottom side view of binary tree | ||
3 | ||
/ \ | ||
9 20 | ||
/ \ | ||
15 7 | ||
↑ ↑ ↑ ↑ | ||
9 15 20 7 | ||
>>> binary_tree_bottom_side_view(make_tree()) | ||
[9, 15, 20, 7] | ||
>>> binary_tree_bottom_side_view(None) | ||
[] | ||
""" | ||
from collections import defaultdict | ||
|
||
def breadth_first_search(root: TreeNode, bottom_view: list[int]) -> None: | ||
""" | ||
A breadth first search traversal with defaultdict ds to append | ||
the values of tree from bottom view | ||
""" | ||
queue = [(root, 0)] | ||
lookup = defaultdict(list) | ||
|
||
while queue: | ||
first = queue.pop(0) | ||
node, hd = first | ||
lookup[hd].append(node.val) | ||
|
||
if node.left: | ||
queue.append((node.left, hd - 1)) | ||
if node.right: | ||
queue.append((node.right, hd + 1)) | ||
|
||
for pair in sorted(lookup.items(), key=lambda each: each[0]): | ||
bottom_view.append(pair[1][-1]) | ||
|
||
bottom_view: list = [] | ||
if not root: | ||
return bottom_view | ||
|
||
breadth_first_search(root, bottom_view) | ||
return bottom_view | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |