Skip to content
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

Duplicate implementation found in data_struture/binary_tree/binary_search_tree_recursive.py Fixes: #8098 #11142

Closed
wants to merge 1 commit into from

Conversation

adesh1998
Copy link

Describe your change:

Fixes: #8098

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@cclauss
Copy link
Member

cclauss commented Nov 5, 2023

Let's be super careful about deleting the hard work of other people.

Given the extensive diff between these files...

API differences

@ diff data_structures/binary_tree/binary_search_tree.py data_structures/binary_tree/binary_search_tree_recursive.py | grep "def "

>     def __init__(self, label: int, parent: Node | None) -> None:
>     def __init__(self) -> None:
>     def empty(self) -> None:
>     def is_empty(self) -> bool:
>     def put(self, label: int) -> None:
<     def __iter__(self) -> Iterator[int]:
<     def __repr__(self) -> str:
>     def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Node:
<     def is_right(self) -> bool:
>     def search(self, label: int) -> Node:
<     def __bool__(self) -> bool:
>     def _search(self, node: Node | None, label: int) -> Node:
<     def __iter__(self) -> Iterator[int]:
<     def __str__(self) -> str:
>     def remove(self, label: int) -> None:
<     def __reassign_nodes(self, node: Node, new_children: Node | None) -> None:
>     def _reassign_nodes(self, node: Node, new_children: Node | None) -> None:
<     def empty(self) -> bool:
>     def _get_lowest_node(self, node: Node) -> Node:
<     def __insert(self, value) -> None:
>     def exists(self, label: int) -> bool:
<     def insert(self, *values) -> None:
<     def search(self, value) -> Node | None:
<     def get_max(self, node: Node | None = None) -> Node | None:
>     def get_max_label(self) -> int:
<     def get_min(self, node: Node | None = None) -> Node | None:
<     def remove(self, value: int) -> None:
<     def preorder_traverse(self, node: Node | None) -> Iterable:
<     def traversal_tree(self, traversal_function=None) -> Any:
>     def get_min_label(self) -> int:
<     def inorder(self, arr: list, node: Node | None) -> None:
<     def find_kth_smallest(self, k: int, node: Node) -> int:
< def inorder(curr_node: Node | None) -> list[Node]:
< def postorder(curr_node: Node | None) -> list[Node]:
>     def inorder_traversal(self) -> Iterator[Node]:
>     def _inorder_traversal(self, node: Node | None) -> Iterator[Node]:
>     def preorder_traversal(self) -> Iterator[Node]:
>     def _preorder_traversal(self, node: Node | None) -> Iterator[Node]:
>     def _get_binary_search_tree() -> BinarySearchTree:
>     def test_put(self) -> None:
>     def test_search(self) -> None:
>     def test_remove(self) -> None:
>     def test_remove_2(self) -> None:
>     def test_empty(self) -> None:
>     def test_is_empty(self) -> None:
>     def test_exists(self) -> None:
>     def test_get_max_label(self) -> None:
>     def test_get_min_label(self) -> None:
>     def test_inorder_traversal(self) -> None:
>     def test_preorder_traversal(self) -> None:
> def binary_search_tree_example() -> None:

All differences

% diff data_structures/binary_tree/binary_search_tree.py data_structures/binary_tree

/binary_search_tree_recursive.py
1,2c1,2
< r"""
< A binary search Tree
---
> """
> This is a python3 implementation of binary search tree using recursion
4,11c4,5
< Example
<               8
<              / \
<             3   10
<            / \    \
<           1   6    14
<              / \   /
<             4   7 13
---
> To run tests:
> python -m unittest binary_search_tree_recursive.py
13,16c7,10
< >>> t = BinarySearchTree()
< >>> t.insert(8, 3, 6, 1, 10, 14, 13, 4, 7)
< >>> print(" ".join(repr(i.value) for i in t.traversal_tree()))
< 8 3 1 6 4 7 10 14 13
---
> To run an example:
> python binary_search_tree_recursive.py
> """
> from __future__ import annotations
18,25c12,13
< >>> tuple(i.value for i in t.traversal_tree(inorder))
< (1, 3, 4, 6, 7, 8, 10, 13, 14)
< >>> tuple(t)
< (1, 3, 4, 6, 7, 8, 10, 13, 14)
< >>> t.find_kth_smallest(3, t.root)
< 4
< >>> tuple(t)[3-1]
< 4
---
> import unittest
> from collections.abc import Iterator
27,36c15
< >>> print(" ".join(repr(i.value) for i in t.traversal_tree(postorder)))
< 1 4 7 6 3 13 14 10 8
< >>> t.remove(20)
< Traceback (most recent call last):
<     ...
< ValueError: Value 20 not found
< >>> BinarySearchTree().search(6)
< Traceback (most recent call last):
<     ...
< IndexError: Warning: Tree is empty! please use another.
---
> import pytest
38d16
< Other example:
40,43c18,23
< >>> testlist = (8, 3, 6, 1, 10, 14, 13, 4, 7)
< >>> t = BinarySearchTree()
< >>> for i in testlist:
< ...     t.insert(i)
---
> class Node:
>     def __init__(self, label: int, parent: Node | None) -> None:
>         self.label = label
>         self.parent = parent
>         self.left: Node | None = None
>         self.right: Node | None = None
45,47d24
< Prints all the elements of the list in order traversal
< >>> print(t)
< {'8': ({'3': (1, {'6': (4, 7)})}, {'10': (None, {'14': (13, None)})})}
49,57c26,28
< Test existence
< >>> t.search(6) is not None
< True
< >>> 6 in t
< True
< >>> t.search(-1) is not None
< False
< >>> -1 in t
< False
---
> class BinarySearchTree:
>     def __init__(self) -> None:
>         self.root: Node | None = None
59,62c30,32
< >>> t.search(6).is_right
< True
< >>> t.search(1).is_right
< False
---
>     def empty(self) -> None:
>         """
>         Empties the tree
64,83c34,39
< >>> t.get_max().value
< 14
< >>> max(t)
< 14
< >>> t.get_min().value
< 1
< >>> min(t)
< 1
< >>> t.empty()
< False
< >>> not t
< False
< >>> for i in testlist:
< ...     t.remove(i)
< >>> t.empty()
< True
< >>> not t
< True
< """
< from __future__ import annotations
---
>         >>> t = BinarySearchTree()
>         >>> assert t.root is None
>         >>> t.put(8)
>         >>> assert t.root is not None
>         """
>         self.root = None
85,87c41,43
< from collections.abc import Iterable, Iterator
< from dataclasses import dataclass
< from typing import Any
---
>     def is_empty(self) -> bool:
>         """
>         Checks if the tree is empty
88a45,52
>         >>> t = BinarySearchTree()
>         >>> t.is_empty()
>         True
>         >>> t.put(8)
>         >>> t.is_empty()
>         False
>         """
>         return self.root is None
90,95c54,56
< @dataclass
< class Node:
<     value: int
<     left: Node | None = None
<     right: Node | None = None
<     parent: Node | None = None  # Added in order to delete a node easier
---
>     def put(self, label: int) -> None:
>         """
>         Put a new node in the tree
97c58,69
<     def __iter__(self) -> Iterator[int]:
---
>         >>> t = BinarySearchTree()
>         >>> t.put(8)
>         >>> assert t.root.parent is None
>         >>> assert t.root.label == 8
>
>         >>> t.put(10)
>         >>> assert t.root.right.parent == t.root
>         >>> assert t.root.right.label == 10
>
>         >>> t.put(3)
>         >>> assert t.root.left.parent == t.root
>         >>> assert t.root.left.label == 3
99,106c71
<         >>> list(Node(0))
<         [0]
<         >>> list(Node(0, Node(-1), Node(1), None))
<         [-1, 0, 1]
<         """
<         yield from self.left or []
<         yield self.value
<         yield from self.right or []
---
>         self.root = self._put(self.root, label)
108,109c73,83
<     def __repr__(self) -> str:
<         from pprint import pformat
---
>     def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Node:
>         if node is None:
>             node = Node(label, parent)
>         else:
>             if label < node.label:
>                 node.left = self._put(node.left, label, node)
>             elif label > node.label:
>                 node.right = self._put(node.right, label, node)
>             else:
>                 msg = f"Node with label {label} already exists"
>                 raise ValueError(msg)
111,113c85
<         if self.left is None and self.right is None:
<             return str(self.value)
<         return pformat({f"{self.value}": (self.left, self.right)}, indent=1)
---
>         return node
115,117c87,89
<     @property
<     def is_right(self) -> bool:
<         return bool(self.parent and self is self.parent.right)
---
>     def search(self, label: int) -> Node:
>         """
>         Searches a node in the tree
118a91,95
>         >>> t = BinarySearchTree()
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> node = t.search(8)
>         >>> assert node.label == 8
120,122c97,102
< @dataclass
< class BinarySearchTree:
<     root: Node | None = None
---
>         >>> node = t.search(3)
>         Traceback (most recent call last):
>             ...
>         ValueError: Node with label 3 does not exist
>         """
>         return self._search(self.root, label)
124,125c104,112
<     def __bool__(self) -> bool:
<         return bool(self.root)
---
>     def _search(self, node: Node | None, label: int) -> Node:
>         if node is None:
>             msg = f"Node with label {label} does not exist"
>             raise ValueError(msg)
>         else:
>             if label < node.label:
>                 node = self._search(node.left, label)
>             elif label > node.label:
>                 node = self._search(node.right, label)
127,128c114
<     def __iter__(self) -> Iterator[int]:
<         yield from self.root or []
---
>         return node
130c116
<     def __str__(self) -> str:
---
>     def remove(self, label: int) -> None:
132,134c118
<         Return a string of all the Nodes using in order traversal
<         """
<         return str(self.root)
---
>         Removes a node in the tree
136,137c120,148
<     def __reassign_nodes(self, node: Node, new_children: Node | None) -> None:
<         if new_children is not None:  # reset its kids
---
>         >>> t = BinarySearchTree()
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.remove(8)
>         >>> assert t.root.label == 10
>
>         >>> t.remove(3)
>         Traceback (most recent call last):
>             ...
>         ValueError: Node with label 3 does not exist
>         """
>         node = self.search(label)
>         if node.right and node.left:
>             lowest_node = self._get_lowest_node(node.right)
>             lowest_node.left = node.left
>             lowest_node.right = node.right
>             node.left.parent = lowest_node
>             if node.right:
>                 node.right.parent = lowest_node
>             self._reassign_nodes(node, lowest_node)
>         elif not node.right and node.left:
>             self._reassign_nodes(node, node.left)
>         elif node.right and not node.left:
>             self._reassign_nodes(node, node.right)
>         else:
>             self._reassign_nodes(node, None)
>
>     def _reassign_nodes(self, node: Node, new_children: Node | None) -> None:
>         if new_children:
139,140c150,152
<         if node.parent is not None:  # reset its parent
<             if node.is_right:  # If it is the right child
---
>
>         if node.parent:
>             if node.parent.right == node:
147,148c159,164
<     def empty(self) -> bool:
<         return self.root is None
---
>     def _get_lowest_node(self, node: Node) -> Node:
>         if node.left:
>             lowest_node = self._get_lowest_node(node.left)
>         else:
>             lowest_node = node
>             self._reassign_nodes(node, node.right)
150c166,168
<     def __insert(self, value) -> None:
---
>         return lowest_node
>
>     def exists(self, label: int) -> bool:
152,174c170
<         Insert a new node in Binary Search Tree with value label
<         """
<         new_node = Node(value)  # create a new Node
<         if self.empty():  # if Tree is empty
<             self.root = new_node  # set its root
<         else:  # Tree is not empty
<             parent_node = self.root  # from root
<             if parent_node is None:
<                 return
<             while True:  # While we don't get to a leaf
<                 if value < parent_node.value:  # We go left
<                     if parent_node.left is None:
<                         parent_node.left = new_node  # We insert the new node in a leaf
<                         break
<                     else:
<                         parent_node = parent_node.left
<                 else:
<                     if parent_node.right is None:
<                         parent_node.right = new_node
<                         break
<                     else:
<                         parent_node = parent_node.right
<             new_node.parent = parent_node
---
>         Checks if a node exists in the tree
176,178c172,176
<     def insert(self, *values) -> None:
<         for value in values:
<             self.__insert(value)
---
>         >>> t = BinarySearchTree()
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.exists(8)
>         True
180,188c178,185
<     def search(self, value) -> Node | None:
<         if self.empty():
<             raise IndexError("Warning: Tree is empty! please use another.")
<         else:
<             node = self.root
<             # use lazy evaluation here to avoid NoneType Attribute error
<             while node is not None and node.value is not value:
<                 node = node.left if value < node.value else node.right
<             return node
---
>         >>> t.exists(3)
>         False
>         """
>         try:
>             self.search(label)
>             return True
>         except ValueError:
>             return False
190c187
<     def get_max(self, node: Node | None = None) -> Node | None:
---
>     def get_max_label(self) -> int:
192,197c189
<         We go deep on the right branch
<         """
<         if node is None:
<             if self.root is None:
<                 return None
<             node = self.root
---
>         Gets the max label inserted in the tree
199,202c191,195
<         if not self.empty():
<             while node.right is not None:
<                 node = node.right
<         return node
---
>         >>> t = BinarySearchTree()
>         >>> t.get_max_label()
>         Traceback (most recent call last):
>             ...
>         ValueError: Binary search tree is empty
204c197,200
<     def get_min(self, node: Node | None = None) -> Node | None:
---
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.get_max_label()
>         10
206,209d201
<         We go deep on the left branch
<         """
<         if node is None:
<             node = self.root
211,216c203
<             return None
<         if not self.empty():
<             node = self.root
<             while node.left is not None:
<                 node = node.left
<         return node
---
>             raise ValueError("Binary search tree is empty")
218,223c205,207
<     def remove(self, value: int) -> None:
<         # Look for the node with that label
<         node = self.search(value)
<         if node is None:
<             msg = f"Value {value} not found"
<             raise ValueError(msg)
---
>         node = self.root
>         while node.right is not None:
>             node = node.right
225,238c209
<         if node.left is None and node.right is None:  # If it has no children
<             self.__reassign_nodes(node, None)
<         elif node.left is None:  # Has only right children
<             self.__reassign_nodes(node, node.right)
<         elif node.right is None:  # Has only left children
<             self.__reassign_nodes(node, node.left)
<         else:
<             predecessor = self.get_max(
<                 node.left
<             )  # Gets the max value of the left branch
<             self.remove(predecessor.value)  # type: ignore
<             node.value = (
<                 predecessor.value  # type: ignore
<             )  # Assigns the value to the node to delete and keep tree structure
---
>         return node.label
240,246c211
<     def preorder_traverse(self, node: Node | None) -> Iterable:
<         if node is not None:
<             yield node  # Preorder Traversal
<             yield from self.preorder_traverse(node.left)
<             yield from self.preorder_traverse(node.right)
<
<     def traversal_tree(self, traversal_function=None) -> Any:
---
>     def get_min_label(self) -> int:
248,254c213
<         This function traversal the tree.
<         You can pass a function to traversal the tree as needed by client code
<         """
<         if traversal_function is None:
<             return self.preorder_traverse(self.root)
<         else:
<             return traversal_function(self.root)
---
>         Gets the min label inserted in the tree
256,262c215,219
<     def inorder(self, arr: list, node: Node | None) -> None:
<         """Perform an inorder traversal and append values of the nodes to
<         a list named arr"""
<         if node:
<             self.inorder(arr, node.left)
<             arr.append(node.value)
<             self.inorder(arr, node.right)
---
>         >>> t = BinarySearchTree()
>         >>> t.get_min_label()
>         Traceback (most recent call last):
>             ...
>         ValueError: Binary search tree is empty
264,268c221,227
<     def find_kth_smallest(self, k: int, node: Node) -> int:
<         """Return the kth smallest element in a binary search tree"""
<         arr: list[int] = []
<         self.inorder(arr, node)  # append all values to list using inorder traversal
<         return arr[k - 1]
---
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.get_min_label()
>         8
>         """
>         if self.root is None:
>             raise ValueError("Binary search tree is empty")
269a229,231
>         node = self.root
>         while node.left is not None:
>             node = node.left
271,278c233
< def inorder(curr_node: Node | None) -> list[Node]:
<     """
<     inorder (left, self, right)
<     """
<     node_list = []
<     if curr_node is not None:
<         node_list = inorder(curr_node.left) + [curr_node] + inorder(curr_node.right)
<     return node_list
---
>         return node.label
280,281c235,566
<
< def postorder(curr_node: Node | None) -> list[Node]:
---
>     def inorder_traversal(self) -> Iterator[Node]:
>         """
>         Return the inorder traversal of the tree
>
>         >>> t = BinarySearchTree()
>         >>> [i.label for i in t.inorder_traversal()]
>         []
>
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.put(9)
>         >>> [i.label for i in t.inorder_traversal()]
>         [8, 9, 10]
>         """
>         return self._inorder_traversal(self.root)
>
>     def _inorder_traversal(self, node: Node | None) -> Iterator[Node]:
>         if node is not None:
>             yield from self._inorder_traversal(node.left)
>             yield node
>             yield from self._inorder_traversal(node.right)
>
>     def preorder_traversal(self) -> Iterator[Node]:
>         """
>         Return the preorder traversal of the tree
>
>         >>> t = BinarySearchTree()
>         >>> [i.label for i in t.preorder_traversal()]
>         []
>
>         >>> t.put(8)
>         >>> t.put(10)
>         >>> t.put(9)
>         >>> [i.label for i in t.preorder_traversal()]
>         [8, 10, 9]
>         """
>         return self._preorder_traversal(self.root)
>
>     def _preorder_traversal(self, node: Node | None) -> Iterator[Node]:
>         if node is not None:
>             yield node
>             yield from self._preorder_traversal(node.left)
>             yield from self._preorder_traversal(node.right)
>
>
> class BinarySearchTreeTest(unittest.TestCase):
>     @staticmethod
>     def _get_binary_search_tree() -> BinarySearchTree:
>         r"""
>               8
>              / \
>             3   10
>            / \    \
>           1   6    14
>              / \   /
>             4   7 13
>              \
>               5
>         """
>         t = BinarySearchTree()
>         t.put(8)
>         t.put(3)
>         t.put(6)
>         t.put(1)
>         t.put(10)
>         t.put(14)
>         t.put(13)
>         t.put(4)
>         t.put(7)
>         t.put(5)
>
>         return t
>
>     def test_put(self) -> None:
>         t = BinarySearchTree()
>         assert t.is_empty()
>
>         t.put(8)
>         r"""
>               8
>         """
>         assert t.root is not None
>         assert t.root.parent is None
>         assert t.root.label == 8
>
>         t.put(10)
>         r"""
>               8
>                \
>                 10
>         """
>         assert t.root.right is not None
>         assert t.root.right.parent == t.root
>         assert t.root.right.label == 10
>
>         t.put(3)
>         r"""
>               8
>              / \
>             3   10
>         """
>         assert t.root.left is not None
>         assert t.root.left.parent == t.root
>         assert t.root.left.label == 3
>
>         t.put(6)
>         r"""
>               8
>              / \
>             3   10
>              \
>               6
>         """
>         assert t.root.left.right is not None
>         assert t.root.left.right.parent == t.root.left
>         assert t.root.left.right.label == 6
>
>         t.put(1)
>         r"""
>               8
>              / \
>             3   10
>            / \
>           1   6
>         """
>         assert t.root.left.left is not None
>         assert t.root.left.left.parent == t.root.left
>         assert t.root.left.left.label == 1
>
>         with pytest.raises(ValueError):
>             t.put(1)
>
>     def test_search(self) -> None:
>         t = self._get_binary_search_tree()
>
>         node = t.search(6)
>         assert node.label == 6
>
>         node = t.search(13)
>         assert node.label == 13
>
>         with pytest.raises(ValueError):
>             t.search(2)
>
>     def test_remove(self) -> None:
>         t = self._get_binary_search_tree()
>
>         t.remove(13)
>         r"""
>               8
>              / \
>             3   10
>            / \    \
>           1   6    14
>              / \
>             4   7
>              \
>               5
>         """
>         assert t.root is not None
>         assert t.root.right is not None
>         assert t.root.right.right is not None
>         assert t.root.right.right.right is None
>         assert t.root.right.right.left is None
>
>         t.remove(7)
>         r"""
>               8
>              / \
>             3   10
>            / \    \
>           1   6    14
>              /
>             4
>              \
>               5
>         """
>         assert t.root.left is not None
>         assert t.root.left.right is not None
>         assert t.root.left.right.left is not None
>         assert t.root.left.right.right is None
>         assert t.root.left.right.left.label == 4
>
>         t.remove(6)
>         r"""
>               8
>              / \
>             3   10
>            / \    \
>           1   4    14
>                \
>                 5
>         """
>         assert t.root.left.left is not None
>         assert t.root.left.right.right is not None
>         assert t.root.left.left.label == 1
>         assert t.root.left.right.label == 4
>         assert t.root.left.right.right.label == 5
>         assert t.root.left.right.left is None
>         assert t.root.left.left.parent == t.root.left
>         assert t.root.left.right.parent == t.root.left
>
>         t.remove(3)
>         r"""
>               8
>              / \
>             4   10
>            / \    \
>           1   5    14
>         """
>         assert t.root is not None
>         assert t.root.left.label == 4
>         assert t.root.left.right.label == 5
>         assert t.root.left.left.label == 1
>         assert t.root.left.parent == t.root
>         assert t.root.left.left.parent == t.root.left
>         assert t.root.left.right.parent == t.root.left
>
>         t.remove(4)
>         r"""
>               8
>              / \
>             5   10
>            /      \
>           1        14
>         """
>         assert t.root.left is not None
>         assert t.root.left.left is not None
>         assert t.root.left.label == 5
>         assert t.root.left.right is None
>         assert t.root.left.left.label == 1
>         assert t.root.left.parent == t.root
>         assert t.root.left.left.parent == t.root.left
>
>     def test_remove_2(self) -> None:
>         t = self._get_binary_search_tree()
>
>         t.remove(3)
>         r"""
>               8
>              / \
>             4   10
>            / \    \
>           1   6    14
>              / \   /
>             5   7 13
>         """
>         assert t.root is not None
>         assert t.root.left is not None
>         assert t.root.left.left is not None
>         assert t.root.left.right is not None
>         assert t.root.left.right.left is not None
>         assert t.root.left.right.right is not None
>         assert t.root.left.label == 4
>         assert t.root.left.right.label == 6
>         assert t.root.left.left.label == 1
>         assert t.root.left.right.right.label == 7
>         assert t.root.left.right.left.label == 5
>         assert t.root.left.parent == t.root
>         assert t.root.left.right.parent == t.root.left
>         assert t.root.left.left.parent == t.root.left
>         assert t.root.left.right.left.parent == t.root.left.right
>
>     def test_empty(self) -> None:
>         t = self._get_binary_search_tree()
>         t.empty()
>         assert t.root is None
>
>     def test_is_empty(self) -> None:
>         t = self._get_binary_search_tree()
>         assert not t.is_empty()
>
>         t.empty()
>         assert t.is_empty()
>
>     def test_exists(self) -> None:
>         t = self._get_binary_search_tree()
>
>         assert t.exists(6)
>         assert not t.exists(-1)
>
>     def test_get_max_label(self) -> None:
>         t = self._get_binary_search_tree()
>
>         assert t.get_max_label() == 14
>
>         t.empty()
>         with pytest.raises(ValueError):
>             t.get_max_label()
>
>     def test_get_min_label(self) -> None:
>         t = self._get_binary_search_tree()
>
>         assert t.get_min_label() == 1
>
>         t.empty()
>         with pytest.raises(ValueError):
>             t.get_min_label()
>
>     def test_inorder_traversal(self) -> None:
>         t = self._get_binary_search_tree()
>
>         inorder_traversal_nodes = [i.label for i in t.inorder_traversal()]
>         assert inorder_traversal_nodes == [1, 3, 4, 5, 6, 7, 8, 10, 13, 14]
>
>     def test_preorder_traversal(self) -> None:
>         t = self._get_binary_search_tree()
>
>         preorder_traversal_nodes = [i.label for i in t.preorder_traversal()]
>         assert preorder_traversal_nodes == [8, 3, 1, 6, 4, 5, 7, 10, 14, 13]
>
>
> def binary_search_tree_example() -> None:
>     r"""
>     Example
>                   8
>                  / \
>                 3   10
>                / \    \
>               1   6    14
>                  / \   /
>                 4   7 13
>                 \
>                 5
>
>     Example After Deletion
>                   4
>                  / \
>                 1   7
>                      \
>                       5
>
283,288d567
<     postOrder (left, right, self)
<     """
<     node_list = []
<     if curr_node is not None:
<         node_list = postorder(curr_node.left) + postorder(curr_node.right) + [curr_node]
<     return node_list
289a569,579
>     t = BinarySearchTree()
>     t.put(8)
>     t.put(3)
>     t.put(6)
>     t.put(1)
>     t.put(10)
>     t.put(14)
>     t.put(13)
>     t.put(4)
>     t.put(7)
>     t.put(5)
291,292c581,593
< if __name__ == "__main__":
<     import doctest
---
>     print(
>         """
>             8
>            / \\
>           3   10
>          / \\    \\
>         1   6    14
>            / \\   /
>           4   7 13
>            \\
>             5
>         """
>     )
294c595,642
<     doctest.testmod(verbose=True)
---
>     print("Label 6 exists:", t.exists(6))
>     print("Label 13 exists:", t.exists(13))
>     print("Label -1 exists:", t.exists(-1))
>     print("Label 12 exists:", t.exists(12))
>
>     # Prints all the elements of the list in inorder traversal
>     inorder_traversal_nodes = [i.label for i in t.inorder_traversal()]
>     print("Inorder traversal:", inorder_traversal_nodes)
>
>     # Prints all the elements of the list in preorder traversal
>     preorder_traversal_nodes = [i.label for i in t.preorder_traversal()]
>     print("Preorder traversal:", preorder_traversal_nodes)
>
>     print("Max. label:", t.get_max_label())
>     print("Min. label:", t.get_min_label())
>
>     # Delete elements
>     print("\nDeleting elements 13, 10, 8, 3, 6, 14")
>     print(
>         """
>           4
>          / \\
>         1   7
>              \\
>               5
>         """
>     )
>     t.remove(13)
>     t.remove(10)
>     t.remove(8)
>     t.remove(3)
>     t.remove(6)
>     t.remove(14)
>
>     # Prints all the elements of the list in inorder traversal after delete
>     inorder_traversal_nodes = [i.label for i in t.inorder_traversal()]
>     print("Inorder traversal after delete:", inorder_traversal_nodes)
>
>     # Prints all the elements of the list in preorder traversal after delete
>     preorder_traversal_nodes = [i.label for i in t.preorder_traversal()]
>     print("Preorder traversal after delete:", preorder_traversal_nodes)
>
>     print("Max. label:", t.get_max_label())
>     print("Min. label:", t.get_min_label())
>
>
> if __name__ == "__main__":
>     binary_search_tree_example()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Concatenate/consolidate all algorithms with different implementations
2 participants