[Binary Tree] Different views of binary tree added
diff --git a/data_structures/binary_tree/diff_views_of_binary_tree.py b/data_structures/binary_tree/diff_views_of_binary_tree.py
new file mode 100644
index 000000000000..3198d8065918
--- /dev/null
+++ b/data_structures/binary_tree/diff_views_of_binary_tree.py
@@ -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()

### Describe your change:
Problem:
Given root of binary Tree, print 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


* [X] Add an algorithm?
* [ ] Fix a bug or typo in an existing algorithm?
* [ ] Documentation change?

### Checklist:
* [X] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md).
* [X] This pull request is all my own work -- I have not plagiarized.
* [X] I know that pull requests will not be merged if they fail the automated tests.
* [X] This PR only changes one algorithm file.  To ease review, please open separate PRs for separate algorithms.
* [X] All new Python files are placed inside an existing directory.
* [X] All filenames are in all lowercase characters with no spaces or dashes.
* [X] All functions and variable names follow Python naming conventions.
* [X] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
* [X] All functions have [doctests](https://docs.python.org/3/library/doctest.html) that pass the automated testing.
* [X] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
* [X] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.
