From bf44f090d5fcda90a81cb3138c17f789b7f8dca6 Mon Sep 17 00:00:00 2001 From: Adarshsidnal <01fe21bcs288@kletech.ac.in> Date: Thu, 5 Oct 2023 11:03:19 +0530 Subject: [PATCH 1/3] Added an algorithm transfrom bst to greater sum tree --- .../binary_tree/transform_bst_sum_tree.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 data_structures/binary_tree/transform_bst_sum_tree.py diff --git a/data_structures/binary_tree/transform_bst_sum_tree.py b/data_structures/binary_tree/transform_bst_sum_tree.py new file mode 100644 index 000000000000..7b102c0c565f --- /dev/null +++ b/data_structures/binary_tree/transform_bst_sum_tree.py @@ -0,0 +1,126 @@ +from __future__ import annotations +class Node: + """ +prints the inorder Traversal of transformed tree +>>> sum = 0 +>>> root = Node(11) +>>> root.left = Node(2) +>>> root.right = Node(29) +>>> root.left.left = Node(1) +>>> root.left.right = Node(7) +>>> root.right.left = Node(15) +>>> root.right.right = Node(40) +>>> root.right.right.left = Node(35) +>>> printInorder(root) +1 2 7 11 15 29 35 40 + +>>> transformTree(root) + +>>> printInorder(root) +139 137 130 119 104 75 40 0 + +""" + + def __init__(self, number:int) -> None: + self.data = number + self.left = None + self.right = None + +# Recursive function to transform a BST to sum tree. +# This function traverses the tree in reverse inorder so +# that we have visited all greater key nodes of the currently +# visited node +def transform_tree_util(root:Node | None) -> None: + """ + Transform a binary tree into a sum tree. + + Example: + >>> root = Node(11) + >>> root.left = Node(2) + >>> root.right = Node(29) + >>> transformTree(root) + >>> root.data + 60 + >>> root.left.data + 31 + >>> root.right.data + 29 + """ + + # Base case + if (root == None): + return + + # Recur for right subtree + transform_tree_util(root.right) + + # Update sum + global sum + sum = sum + root.data + + # Store old sum in the current node + root.data = sum - root.data + + # Recur for left subtree + transform_tree_util(root.left) + +# A wrapper over transformTreeUtil() +def transform_tree(root:Node | None) -> None: + """ + Transform a binary tree into a sum tree. + + Example: + >>> root = Node(11) + >>> root.left = Node(2) + >>> root.right = Node(29) + >>> transformTree(root) + >>> root.data + 60 + >>> root.left.data + 31 + >>> root.right.data + 29 + """ + + # sum = 0 #Initialize sum + transform_tree_util(root) + +# A utility function to prindorder traversal of a +# binary tree +def print_inorder(root:Node | None): + """ + Perform an inorder traversal of a binary tree and print the nodes. + + Example: + >>> root = Node(11) + >>> root.left = Node(2) + >>> root.right = Node(29) + >>> printInorder(root) + 2 11 29 + """ + + if (root == None): + return + + print_inorder(root.left) + print(root.data, end = " ") + print_inorder(root.right) + +# Driver Program to test above functions +if __name__ == '__main__': + + sum = 0 + root = Node(11) + root.left = Node(2) + root.right = Node(29) + root.left.left = Node(1) + root.left.right = Node(7) + root.right.left = Node(15) + root.right.right = Node(40) + root.right.right.left = Node(35) + + print_inorder(root) + + transform_tree_util(root) + print_inorder(root) + From 9563bf999fd66018a7994be7f4140f6f0e0fde90 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 05:39:25 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../binary_tree/transform_bst_sum_tree.py | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/data_structures/binary_tree/transform_bst_sum_tree.py b/data_structures/binary_tree/transform_bst_sum_tree.py index 7b102c0c565f..114ec72f40c4 100644 --- a/data_structures/binary_tree/transform_bst_sum_tree.py +++ b/data_structures/binary_tree/transform_bst_sum_tree.py @@ -1,39 +1,41 @@ from __future__ import annotations + + class Node: """ -prints the inorder Traversal of transformed tree ->>> sum = 0 ->>> root = Node(11) ->>> root.left = Node(2) ->>> root.right = Node(29) ->>> root.left.left = Node(1) ->>> root.left.right = Node(7) ->>> root.right.left = Node(15) ->>> root.right.right = Node(40) ->>> root.right.right.left = Node(35) ->>> printInorder(root) -1 2 7 11 15 29 35 40 - ->>> transformTree(root) - ->>> printInorder(root) -139 137 130 119 104 75 40 0 - -""" - - def __init__(self, number:int) -> None: + prints the inorder Traversal of transformed tree + >>> sum = 0 + >>> root = Node(11) + >>> root.left = Node(2) + >>> root.right = Node(29) + >>> root.left.left = Node(1) + >>> root.left.right = Node(7) + >>> root.right.left = Node(15) + >>> root.right.right = Node(40) + >>> root.right.right.left = Node(35) + >>> printInorder(root) + 1 2 7 11 15 29 35 40 + + >>> transformTree(root) + + >>> printInorder(root) + 139 137 130 119 104 75 40 0 + """ + + def __init__(self, number: int) -> None: self.data = number self.left = None self.right = None + # Recursive function to transform a BST to sum tree. # This function traverses the tree in reverse inorder so # that we have visited all greater key nodes of the currently # visited node -def transform_tree_util(root:Node | None) -> None: +def transform_tree_util(root: Node | None) -> None: """ Transform a binary tree into a sum tree. - + Example: >>> root = Node(11) >>> root.left = Node(2) @@ -48,7 +50,7 @@ def transform_tree_util(root:Node | None) -> None: """ # Base case - if (root == None): + if root == None: return # Recur for right subtree @@ -64,11 +66,12 @@ def transform_tree_util(root:Node | None) -> None: # Recur for left subtree transform_tree_util(root.left) + # A wrapper over transformTreeUtil() -def transform_tree(root:Node | None) -> None: +def transform_tree(root: Node | None) -> None: """ Transform a binary tree into a sum tree. - + Example: >>> root = Node(11) >>> root.left = Node(2) @@ -85,12 +88,13 @@ def transform_tree(root:Node | None) -> None: # sum = 0 #Initialize sum transform_tree_util(root) + # A utility function to prindorder traversal of a # binary tree -def print_inorder(root:Node | None): +def print_inorder(root: Node | None): """ Perform an inorder traversal of a binary tree and print the nodes. - + Example: >>> root = Node(11) >>> root.left = Node(2) @@ -99,16 +103,16 @@ def print_inorder(root:Node | None): 2 11 29 """ - if (root == None): + if root == None: return print_inorder(root.left) - print(root.data, end = " ") + print(root.data, end=" ") print_inorder(root.right) -# Driver Program to test above functions -if __name__ == '__main__': +# Driver Program to test above functions +if __name__ == "__main__": sum = 0 root = Node(11) root.left = Node(2) @@ -123,4 +127,3 @@ def print_inorder(root:Node | None): transform_tree_util(root) print_inorder(root) - From 971a3f0ec457686a169e9621ffac48932d9540c7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 17 Oct 2023 00:53:25 +0200 Subject: [PATCH 3/3] Update and rename transform_bst_sum_tree.py to is_sum_tree.py --- data_structures/binary_tree/is_sum_tree.py | 161 ++++++++++++++++++ .../binary_tree/transform_bst_sum_tree.py | 129 -------------- 2 files changed, 161 insertions(+), 129 deletions(-) create mode 100644 data_structures/binary_tree/is_sum_tree.py delete mode 100644 data_structures/binary_tree/transform_bst_sum_tree.py diff --git a/data_structures/binary_tree/is_sum_tree.py b/data_structures/binary_tree/is_sum_tree.py new file mode 100644 index 000000000000..3f9cf1d560a6 --- /dev/null +++ b/data_structures/binary_tree/is_sum_tree.py @@ -0,0 +1,161 @@ +""" +Is a binary tree a sum tree where the value of every non-leaf node is equal to the sum +of the values of its left and right subtrees? +https://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-sumtree +""" +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass + + +@dataclass +class Node: + data: int + left: Node | None = None + right: Node | None = None + + def __iter__(self) -> Iterator[int]: + """ + >>> root = Node(2) + >>> list(root) + [2] + >>> root.left = Node(1) + >>> tuple(root) + (1, 2) + """ + if self.left: + yield from self.left + yield self.data + if self.right: + yield from self.right + + def __len__(self) -> int: + """ + >>> root = Node(2) + >>> len(root) + 1 + >>> root.left = Node(1) + >>> len(root) + 2 + """ + return sum(1 for _ in self) + + @property + def is_sum_node(self) -> bool: + """ + >>> root = Node(3) + >>> root.is_sum_node + True + >>> root.left = Node(1) + >>> root.is_sum_node + False + >>> root.right = Node(2) + >>> root.is_sum_node + True + """ + if not self.left and not self.right: + return True # leaf nodes are considered sum nodes + left_sum = sum(self.left) if self.left else 0 + right_sum = sum(self.right) if self.right else 0 + return all( + ( + self.data == left_sum + right_sum, + self.left.is_sum_node if self.left else True, + self.right.is_sum_node if self.right else True, + ) + ) + + +@dataclass +class BinaryTree: + root: Node + + def __iter__(self) -> Iterator[int]: + """ + >>> list(BinaryTree.build_a_tree()) + [1, 2, 7, 11, 15, 29, 35, 40] + """ + return iter(self.root) + + def __len__(self) -> int: + """ + >>> len(BinaryTree.build_a_tree()) + 8 + """ + return len(self.root) + + def __str__(self) -> str: + """ + Returns a string representation of the inorder traversal of the binary tree. + + >>> str(list(BinaryTree.build_a_tree())) + '[1, 2, 7, 11, 15, 29, 35, 40]' + """ + return str(list(self)) + + @property + def is_sum_tree(self) -> bool: + """ + >>> BinaryTree.build_a_tree().is_sum_tree + False + >>> BinaryTree.build_a_sum_tree().is_sum_tree + True + """ + return self.root.is_sum_node + + @classmethod + def build_a_tree(cls) -> BinaryTree: + r""" + Create a binary tree with the specified structure: + 11 + / \ + 2 29 + / \ / \ + 1 7 15 40 + \ + 35 + >>> list(BinaryTree.build_a_tree()) + [1, 2, 7, 11, 15, 29, 35, 40] + """ + tree = BinaryTree(Node(11)) + root = tree.root + root.left = Node(2) + root.right = Node(29) + root.left.left = Node(1) + root.left.right = Node(7) + root.right.left = Node(15) + root.right.right = Node(40) + root.right.right.left = Node(35) + return tree + + @classmethod + def build_a_sum_tree(cls) -> BinaryTree: + r""" + Create a binary tree with the specified structure: + 26 + / \ + 10 3 + / \ \ + 4 6 3 + >>> list(BinaryTree.build_a_sum_tree()) + [4, 10, 6, 26, 3, 3] + """ + tree = BinaryTree(Node(26)) + root = tree.root + root.left = Node(10) + root.right = Node(3) + root.left.left = Node(4) + root.left.right = Node(6) + root.right.right = Node(3) + return tree + + +if __name__ == "__main__": + from doctest import testmod + + testmod() + tree = BinaryTree.build_a_tree() + print(f"{tree} has {len(tree)} nodes and {tree.is_sum_tree = }.") + tree = BinaryTree.build_a_sum_tree() + print(f"{tree} has {len(tree)} nodes and {tree.is_sum_tree = }.") diff --git a/data_structures/binary_tree/transform_bst_sum_tree.py b/data_structures/binary_tree/transform_bst_sum_tree.py deleted file mode 100644 index 114ec72f40c4..000000000000 --- a/data_structures/binary_tree/transform_bst_sum_tree.py +++ /dev/null @@ -1,129 +0,0 @@ -from __future__ import annotations - - -class Node: - """ - prints the inorder Traversal of transformed tree - >>> sum = 0 - >>> root = Node(11) - >>> root.left = Node(2) - >>> root.right = Node(29) - >>> root.left.left = Node(1) - >>> root.left.right = Node(7) - >>> root.right.left = Node(15) - >>> root.right.right = Node(40) - >>> root.right.right.left = Node(35) - >>> printInorder(root) - 1 2 7 11 15 29 35 40 - - >>> transformTree(root) - - >>> printInorder(root) - 139 137 130 119 104 75 40 0 - """ - - def __init__(self, number: int) -> None: - self.data = number - self.left = None - self.right = None - - -# Recursive function to transform a BST to sum tree. -# This function traverses the tree in reverse inorder so -# that we have visited all greater key nodes of the currently -# visited node -def transform_tree_util(root: Node | None) -> None: - """ - Transform a binary tree into a sum tree. - - Example: - >>> root = Node(11) - >>> root.left = Node(2) - >>> root.right = Node(29) - >>> transformTree(root) - >>> root.data - 60 - >>> root.left.data - 31 - >>> root.right.data - 29 - """ - - # Base case - if root == None: - return - - # Recur for right subtree - transform_tree_util(root.right) - - # Update sum - global sum - sum = sum + root.data - - # Store old sum in the current node - root.data = sum - root.data - - # Recur for left subtree - transform_tree_util(root.left) - - -# A wrapper over transformTreeUtil() -def transform_tree(root: Node | None) -> None: - """ - Transform a binary tree into a sum tree. - - Example: - >>> root = Node(11) - >>> root.left = Node(2) - >>> root.right = Node(29) - >>> transformTree(root) - >>> root.data - 60 - >>> root.left.data - 31 - >>> root.right.data - 29 - """ - - # sum = 0 #Initialize sum - transform_tree_util(root) - - -# A utility function to prindorder traversal of a -# binary tree -def print_inorder(root: Node | None): - """ - Perform an inorder traversal of a binary tree and print the nodes. - - Example: - >>> root = Node(11) - >>> root.left = Node(2) - >>> root.right = Node(29) - >>> printInorder(root) - 2 11 29 - """ - - if root == None: - return - - print_inorder(root.left) - print(root.data, end=" ") - print_inorder(root.right) - - -# Driver Program to test above functions -if __name__ == "__main__": - sum = 0 - root = Node(11) - root.left = Node(2) - root.right = Node(29) - root.left.left = Node(1) - root.left.right = Node(7) - root.right.left = Node(15) - root.right.right = Node(40) - root.right.right.left = Node(35) - - print_inorder(root) - - transform_tree_util(root) - print_inorder(root)