From 2e1cf54887bf4e29256765f98ac2c12b8b55a763 Mon Sep 17 00:00:00 2001 From: Saswat Susmoy <72549122+Saswatsusmoy@users.noreply.github.com> Date: Sat, 14 Oct 2023 00:23:50 +0530 Subject: [PATCH 1/3] Update basic_binary_tree.py --- .../binary_tree/basic_binary_tree.py | 198 ++++++++++-------- 1 file changed, 105 insertions(+), 93 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 65dccf247b51..845c1ce39935 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -1,101 +1,113 @@ from __future__ import annotations +from typing import Optional -class Node: - """ - A Node has data variable and pointers to Nodes to its left and right. - """ +class Node: def __init__(self, data: int) -> None: - self.data = data - self.left: Node | None = None - self.right: Node | None = None - - -def display(tree: Node | None) -> None: # In Order traversal of the tree - """ - >>> root = Node(1) - >>> root.left = Node(0) - >>> root.right = Node(2) - >>> display(root) - 0 - 1 - 2 - >>> display(root.right) - 2 - """ - if tree: - display(tree.left) - print(tree.data) - display(tree.right) - - -def depth_of_tree(tree: Node | None) -> int: - """ - Recursive function that returns the depth of a binary tree. - - >>> root = Node(0) - >>> depth_of_tree(root) - 1 - >>> root.left = Node(0) - >>> depth_of_tree(root) - 2 - >>> root.right = Node(0) - >>> depth_of_tree(root) - 2 - >>> root.left.right = Node(0) - >>> depth_of_tree(root) - 3 - >>> depth_of_tree(root.left) - 2 - """ - return 1 + max(depth_of_tree(tree.left), depth_of_tree(tree.right)) if tree else 0 - - -def is_full_binary_tree(tree: Node) -> bool: - """ - Returns True if this is a full binary tree - - >>> root = Node(0) - >>> is_full_binary_tree(root) - True - >>> root.left = Node(0) - >>> is_full_binary_tree(root) - False - >>> root.right = Node(0) - >>> is_full_binary_tree(root) - True - >>> root.left.left = Node(0) - >>> is_full_binary_tree(root) - False - >>> root.right.right = Node(0) - >>> is_full_binary_tree(root) - False - """ - if not tree: - return True - if tree.left and tree.right: - return is_full_binary_tree(tree.left) and is_full_binary_tree(tree.right) - else: - return not tree.left and not tree.right - - -def main() -> None: # Main function for testing. - tree = Node(1) - tree.left = Node(2) - tree.right = Node(3) - tree.left.left = Node(4) - tree.left.right = Node(5) - tree.left.right.left = Node(6) - tree.right.left = Node(7) - tree.right.left.left = Node(8) - tree.right.left.left.right = Node(9) - - print(is_full_binary_tree(tree)) - print(depth_of_tree(tree)) - print("Tree is: ") - display(tree) + self.data: int = data + self.left: Optional[Node] = None # noqa: UP007 + self.right: Optional[Node] = None # noqa: UP007 + + def display(self, node: Optional[Node] = None) -> None: # noqa: UP007 + if node is None: + node = self + if node: + self.display(node.left) + print(node.data) + self.display(node.right) + + +class BinaryTree: + def __init__(self, root: Optional[Node] = None) -> None: # noqa: UP007 + self.root: Optional[Node] = root # noqa: UP007 + + def display(self, node: Optional[Node] = None) -> None: # noqa: UP007 + """ + Prints the tree in order traversal + + Examples: + >>> tree = BinaryTree(Node(1)) + >>> tree.display() + 1 + + >>> tree.root.left = Node(2) + >>> tree.root.right = Node(3) + >>> tree.display() + 2 + 1 + 3 + """ + if node is None: + node = self.root + if node: + self.display(node.left) + print(node.data) + self.display(node.right) + + def depth(self) -> int: + """ + Returns the depth of the tree + + Examples: + + >>> tree = BinaryTree(Node(1)) + >>> tree.depth() + 1 + + >>> tree.root.left = Node(2) + >>> tree.depth() + 2 + + >>> tree.root.right = Node(3) + >>> tree.depth() + 2 + """ + if self.root is None: + return 0 + else: + return self._depth(self.root) + + def _depth(self, node: Optional[Node]) -> int: # noqa: UP007 + if node is None: + return 0 + else: + return 1 + max(self._depth(node.left), self._depth(node.right)) + + def is_full(self) -> bool: + """ + Returns True if the tree is full + + Examples: + + >>> tree = BinaryTree(Node(1)) + >>> tree.is_full() + True + + >>> tree.root.left = Node(2) + >>> tree.is_full() + False + + >>> tree.root.right = Node(3) + >>> tree.is_full() + True + """ + if self.root is None: + return True + else: + return self._is_full(self.root) + + def _is_full(self, node: Node) -> bool: + if node is None: + return True + if node.left is None and node.right is None: + return True + if node.left is not None and node.right is not None: + return self._is_full(node.left) and self._is_full(node.right) + return False if __name__ == "__main__": - main() + import doctest + + doctest.testmod() From 76c519b0175859f15d22b2467f296f07da158346 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 16 Oct 2023 16:40:13 +0200 Subject: [PATCH 2/3] Update basic_binary_tree.py --- .../binary_tree/basic_binary_tree.py | 150 +++++++++--------- 1 file changed, 74 insertions(+), 76 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 845c1ce39935..453b302b05b4 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -1,111 +1,109 @@ from __future__ import annotations -from typing import Optional +from collections.abc import Iterator +from dataclasses import dataclass +@dataclass class Node: - def __init__(self, data: int) -> None: - self.data: int = data - self.left: Optional[Node] = None # noqa: UP007 - self.right: Optional[Node] = None # noqa: UP007 + data: int + left: Node | None = None + right: Node | None = None - def display(self, node: Optional[Node] = None) -> None: # noqa: UP007 - if node is None: - node = self - if node: - self.display(node.left) - print(node.data) - self.display(node.right) + def __iter__(self) -> Iterator[int]: + if self.left: + yield from self.left + yield self.data + if self.right: + yield from self.right + def __len__(self) -> int: + return sum(1 for _ in self) + def is_full(self) -> bool: + if not self or (not self.left and not self.right): + return True + if self.left and self.right: + return self.left.is_full() and self.right.is_full() + return False + + +@dataclass class BinaryTree: - def __init__(self, root: Optional[Node] = None) -> None: # noqa: UP007 - self.root: Optional[Node] = root # noqa: UP007 + root: Node - def display(self, node: Optional[Node] = None) -> None: # noqa: UP007 - """ - Prints the tree in order traversal + def __iter__(self) -> Iterator[int]: + return iter(self.root) - Examples: - >>> tree = BinaryTree(Node(1)) - >>> tree.display() - 1 + def __len__(self) -> int: + return len(self.root) - >>> tree.root.left = Node(2) - >>> tree.root.right = Node(3) - >>> tree.display() - 2 - 1 + @classmethod + def small_tree(cls) -> BinaryTree: + """ + Return a small binary tree with 3 nodes. + >>> binary_tree = BinaryTree.small_tree() + >>> len(binary_tree) 3 + >>> list(binary_tree) + [1, 2, 3] + """ + binary_tree = BinaryTree(Node(2)) + binary_tree.root.left = Node(1) + binary_tree.root.right = Node(3) + return binary_tree + + + @classmethod + def medium_tree(cls) -> BinaryTree: + """ + Return a medium binary tree with 3 nodes. + >>> binary_tree = BinaryTree.medium_tree() + >>> len(binary_tree) + 7 + >>> list(binary_tree) + [1, 2, 3, 4, 5, 6, 7] """ - if node is None: - node = self.root - if node: - self.display(node.left) - print(node.data) - self.display(node.right) + binary_tree = BinaryTree(Node(4)) + binary_tree.root.left = two = Node(2) + two.left = Node(1) + two.right = Node(3) + binary_tree.root.right = five = Node(5) + five.right = six = Node(6) + six.right = Node(7) + return binary_tree + def depth(self) -> int: """ Returns the depth of the tree - Examples: - - >>> tree = BinaryTree(Node(1)) - >>> tree.depth() + >>> BinaryTree(Node(1)).depth() 1 - - >>> tree.root.left = Node(2) - >>> tree.depth() - 2 - - >>> tree.root.right = Node(3) - >>> tree.depth() + >>> BinaryTree.small_tree().depth() 2 + >>> BinaryTree.medium_tree().depth() + 4 """ - if self.root is None: - return 0 - else: - return self._depth(self.root) + return self._depth(self.root) - def _depth(self, node: Optional[Node]) -> int: # noqa: UP007 - if node is None: + def _depth(self, node: Node | None) -> int: # noqa: UP007 + if not node: return 0 - else: - return 1 + max(self._depth(node.left), self._depth(node.right)) + return 1 + max(self._depth(node.left), self._depth(node.right)) def is_full(self) -> bool: """ Returns True if the tree is full - Examples: - - >>> tree = BinaryTree(Node(1)) - >>> tree.is_full() + >>> BinaryTree(Node(1)).is_full() True - - >>> tree.root.left = Node(2) - >>> tree.is_full() - False - - >>> tree.root.right = Node(3) - >>> tree.is_full() + >>> BinaryTree.small_tree().is_full() True + >>> BinaryTree.medium_tree().is_full() + False """ - if self.root is None: - return True - else: - return self._is_full(self.root) - - def _is_full(self, node: Node) -> bool: - if node is None: - return True - if node.left is None and node.right is None: - return True - if node.left is not None and node.right is not None: - return self._is_full(node.left) and self._is_full(node.right) - return False - + return self.root.is_full() if __name__ == "__main__": import doctest From 848df3555e18187d8c5f3c92abeb94605697b0d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:40:50 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/binary_tree/basic_binary_tree.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data_structures/binary_tree/basic_binary_tree.py b/data_structures/binary_tree/basic_binary_tree.py index 453b302b05b4..0439413d95b5 100644 --- a/data_structures/binary_tree/basic_binary_tree.py +++ b/data_structures/binary_tree/basic_binary_tree.py @@ -53,7 +53,6 @@ def small_tree(cls) -> BinaryTree: binary_tree.root.right = Node(3) return binary_tree - @classmethod def medium_tree(cls) -> BinaryTree: """ @@ -73,7 +72,6 @@ def medium_tree(cls) -> BinaryTree: six.right = Node(7) return binary_tree - def depth(self) -> int: """ Returns the depth of the tree @@ -105,6 +103,7 @@ def is_full(self) -> bool: """ return self.root.is_full() + if __name__ == "__main__": import doctest