Skip to content

Commit fcea18c

Browse files
Adarshsidnalpre-commit-ci[bot]cclauss
authored
Added an algorithm transfrom bst to greater sum tree (TheAlgorithms#9777)
* Added an algorithm transfrom bst to greater sum tree * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update and rename transform_bst_sum_tree.py to is_sum_tree.py --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <[email protected]>
1 parent 922bbee commit fcea18c

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
"""
2+
Is a binary tree a sum tree where the value of every non-leaf node is equal to the sum
3+
of the values of its left and right subtrees?
4+
https://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-sumtree
5+
"""
6+
from __future__ import annotations
7+
8+
from collections.abc import Iterator
9+
from dataclasses import dataclass
10+
11+
12+
@dataclass
13+
class Node:
14+
data: int
15+
left: Node | None = None
16+
right: Node | None = None
17+
18+
def __iter__(self) -> Iterator[int]:
19+
"""
20+
>>> root = Node(2)
21+
>>> list(root)
22+
[2]
23+
>>> root.left = Node(1)
24+
>>> tuple(root)
25+
(1, 2)
26+
"""
27+
if self.left:
28+
yield from self.left
29+
yield self.data
30+
if self.right:
31+
yield from self.right
32+
33+
def __len__(self) -> int:
34+
"""
35+
>>> root = Node(2)
36+
>>> len(root)
37+
1
38+
>>> root.left = Node(1)
39+
>>> len(root)
40+
2
41+
"""
42+
return sum(1 for _ in self)
43+
44+
@property
45+
def is_sum_node(self) -> bool:
46+
"""
47+
>>> root = Node(3)
48+
>>> root.is_sum_node
49+
True
50+
>>> root.left = Node(1)
51+
>>> root.is_sum_node
52+
False
53+
>>> root.right = Node(2)
54+
>>> root.is_sum_node
55+
True
56+
"""
57+
if not self.left and not self.right:
58+
return True # leaf nodes are considered sum nodes
59+
left_sum = sum(self.left) if self.left else 0
60+
right_sum = sum(self.right) if self.right else 0
61+
return all(
62+
(
63+
self.data == left_sum + right_sum,
64+
self.left.is_sum_node if self.left else True,
65+
self.right.is_sum_node if self.right else True,
66+
)
67+
)
68+
69+
70+
@dataclass
71+
class BinaryTree:
72+
root: Node
73+
74+
def __iter__(self) -> Iterator[int]:
75+
"""
76+
>>> list(BinaryTree.build_a_tree())
77+
[1, 2, 7, 11, 15, 29, 35, 40]
78+
"""
79+
return iter(self.root)
80+
81+
def __len__(self) -> int:
82+
"""
83+
>>> len(BinaryTree.build_a_tree())
84+
8
85+
"""
86+
return len(self.root)
87+
88+
def __str__(self) -> str:
89+
"""
90+
Returns a string representation of the inorder traversal of the binary tree.
91+
92+
>>> str(list(BinaryTree.build_a_tree()))
93+
'[1, 2, 7, 11, 15, 29, 35, 40]'
94+
"""
95+
return str(list(self))
96+
97+
@property
98+
def is_sum_tree(self) -> bool:
99+
"""
100+
>>> BinaryTree.build_a_tree().is_sum_tree
101+
False
102+
>>> BinaryTree.build_a_sum_tree().is_sum_tree
103+
True
104+
"""
105+
return self.root.is_sum_node
106+
107+
@classmethod
108+
def build_a_tree(cls) -> BinaryTree:
109+
r"""
110+
Create a binary tree with the specified structure:
111+
11
112+
/ \
113+
2 29
114+
/ \ / \
115+
1 7 15 40
116+
\
117+
35
118+
>>> list(BinaryTree.build_a_tree())
119+
[1, 2, 7, 11, 15, 29, 35, 40]
120+
"""
121+
tree = BinaryTree(Node(11))
122+
root = tree.root
123+
root.left = Node(2)
124+
root.right = Node(29)
125+
root.left.left = Node(1)
126+
root.left.right = Node(7)
127+
root.right.left = Node(15)
128+
root.right.right = Node(40)
129+
root.right.right.left = Node(35)
130+
return tree
131+
132+
@classmethod
133+
def build_a_sum_tree(cls) -> BinaryTree:
134+
r"""
135+
Create a binary tree with the specified structure:
136+
26
137+
/ \
138+
10 3
139+
/ \ \
140+
4 6 3
141+
>>> list(BinaryTree.build_a_sum_tree())
142+
[4, 10, 6, 26, 3, 3]
143+
"""
144+
tree = BinaryTree(Node(26))
145+
root = tree.root
146+
root.left = Node(10)
147+
root.right = Node(3)
148+
root.left.left = Node(4)
149+
root.left.right = Node(6)
150+
root.right.right = Node(3)
151+
return tree
152+
153+
154+
if __name__ == "__main__":
155+
from doctest import testmod
156+
157+
testmod()
158+
tree = BinaryTree.build_a_tree()
159+
print(f"{tree} has {len(tree)} nodes and {tree.is_sum_tree = }.")
160+
tree = BinaryTree.build_a_sum_tree()
161+
print(f"{tree} has {len(tree)} nodes and {tree.is_sum_tree = }.")

0 commit comments

Comments
 (0)