|
1 | | -from typing import List, Generic, TypeVar, Any |
2 | | -from abc import ABC, abstractmethod |
3 | | -from .node import TreeNode |
| 1 | +from datastructures.trees.tree import Tree, TreeNode, T |
| 2 | +from datastructures.trees.binary import BinaryTree, BinaryTreeNode |
4 | 3 |
|
5 | | -T = TypeVar("T", bound=Any) |
6 | | - |
7 | | - |
8 | | -class Tree(ABC, Generic[T]): |
9 | | - """ |
10 | | - Tree abstract base class that defines common methods & properties of a typical Tree data structure |
11 | | - """ |
12 | | - |
13 | | - @abstractmethod |
14 | | - def __len__(self) -> int: |
15 | | - """ |
16 | | - Calculates the number of nodes in the Tree |
17 | | - :returns: number of nodes in the tree |
18 | | - """ |
19 | | - raise NotImplementedError("This method has not been implemented") |
20 | | - |
21 | | - @abstractmethod |
22 | | - def next(self) -> int: |
23 | | - raise NotImplementedError("This method has not been implemented") |
24 | | - |
25 | | - @abstractmethod |
26 | | - def height(self) -> int: |
27 | | - """ |
28 | | - Returns the height of the Tree. That is, the number of edges between the root node and the furthest leaf node. |
29 | | - This can also be the maximum depth of the Tree |
30 | | - This is the number of links from the root to the furthest leaf. |
31 | | - """ |
32 | | - raise NotImplementedError("This method has not been implemented") |
33 | | - |
34 | | - @abstractmethod |
35 | | - def lowest_common_ancestor( |
36 | | - self, node_one: TreeNode, node_two: TreeNode |
37 | | - ) -> TreeNode: |
38 | | - """ |
39 | | - Returns the lowest common ancestor of 2 nodes in the Tree. |
40 | | - :param node_one |
41 | | - :param node_two |
42 | | - :returns the lowest common ancestor of the Tree |
43 | | - :rtype TreeNode |
44 | | - """ |
45 | | - raise NotImplementedError("This method has not been implemented") |
46 | | - |
47 | | - @abstractmethod |
48 | | - def has_next(self) -> bool: |
49 | | - raise NotImplementedError("This method has not been implemented") |
50 | | - |
51 | | - @abstractmethod |
52 | | - def increasing_order_traversal(self) -> TreeNode: |
53 | | - """ |
54 | | - Rearranges the tree in in-order so that the leftmost node in the tree is now the root of the tree |
55 | | - and every node has no left child and only one right child |
56 | | - :returns root of tree of new tree |
57 | | - """ |
58 | | - raise NotImplementedError("This method has not been implemented") |
59 | | - |
60 | | - @abstractmethod |
61 | | - def get_depth(self) -> int: |
62 | | - """ |
63 | | - Gets the depth of the tree or height of the tree |
64 | | - :returns height/depth of the tree |
65 | | - """ |
66 | | - raise NotImplementedError("This method has not been implemented") |
67 | | - |
68 | | - @abstractmethod |
69 | | - def insert_node(self, value) -> TreeNode: |
70 | | - """ |
71 | | - Based on the type of tree, this inserts a node in the Tree |
72 | | - """ |
73 | | - raise NotImplementedError("This method has not been implemented") |
74 | | - |
75 | | - @abstractmethod |
76 | | - def paths(self) -> list: |
77 | | - """ |
78 | | - Prints all the paths of a Tree from root node to leaf nodes |
79 | | - """ |
80 | | - raise NotImplementedError("This method has not been implemented") |
81 | | - |
82 | | - @abstractmethod |
83 | | - def level_order_traversal(self) -> List[T]: |
84 | | - raise NotImplementedError("This method has not been implemented") |
85 | | - |
86 | | - def reverse_level_order_traversal(self) -> List[T]: |
87 | | - """ |
88 | | - Performs a level order traversal on the tree in reverse order where the leaf nodes are first iterated through |
89 | | - and then the internal nodes before the root node is added to the collection |
90 | | -
|
91 | | - Complexity: |
92 | | - Where `n` is the number of nodes in the tree |
93 | | -
|
94 | | - Time Complexity: O(n) as each node in the tree is traversed |
95 | | - Space Complexity: O(n) as each node or node data is stored in a list/collection to be returned |
96 | | -
|
97 | | - Returns: |
98 | | - List: list of nodes or node values/data traversed in a reverse level order fashion. |
99 | | - """ |
100 | | - raise NotImplementedError("This method has not been implemented") |
101 | | - |
102 | | - @abstractmethod |
103 | | - def pre_order_traversal(self) -> List[T]: |
104 | | - """Traverses the tree in pre-order walking the left subtree before finally walking the right subtree returning |
105 | | - a list of values on each node |
106 | | -
|
107 | | - Complexity: |
108 | | - Time Complexity O(n): where n is the number of nodes in the tree, as the algorithm has to traverse all the nodes |
109 | | - in the tree |
110 | | -
|
111 | | - Space Complexity O(h), where h is the height of the tree |
112 | | -
|
113 | | - Returns: |
114 | | - list: list of values of each node |
115 | | - """ |
116 | | - raise NotImplementedError("This method has not been implemented") |
117 | | - |
118 | | - def inorder_traversal(self) -> List[T]: |
119 | | - """ |
120 | | - Walks the left subtree first, then visits the current node, and finally walks the right subtree |
121 | | - The algorithm looks something like this: |
122 | | -
|
123 | | - 1. Check if the current node is empty/null. |
124 | | - 2. Traverse the left subtree by recursively calling the in-order method. |
125 | | - 3. Display the data part of the root (or current node). |
126 | | - 4. Traverse the right subtree by recursively calling the in-order method. |
127 | | -
|
128 | | - Complexity: |
129 | | - Where `n` is the number of nodes in the tree |
130 | | -
|
131 | | - Time Complexity: O(n) as each node in the tree is traversed |
132 | | - Space Complexity: O(n) as each node or node data is stored in a list/collection to be returned |
133 | | -
|
134 | | - Returns: |
135 | | - List: list of nodes or node values/data traversed in inorder traversal fashion. |
136 | | - """ |
137 | | - |
138 | | - def post_order_traversal(self) -> List[T]: |
139 | | - """ |
140 | | - Walks the left subtree first, then the right subtree and finally visits the current node |
141 | | - The algorithm looks something like this: |
142 | | -
|
143 | | - 1. Check if the current node is empty/null. |
144 | | - 2. Traverse the left subtree by recursively calling the post-order method. |
145 | | - 3. Traverse the right subtree by recursively calling the post-order method. |
146 | | - 4. Display the data part of the root (or current node). |
147 | | -
|
148 | | - Complexity: |
149 | | - Where `n` is the number of nodes in the tree |
150 | | -
|
151 | | - Time Complexity: O(n) as each node in the tree is traversed |
152 | | - Space Complexity: O(n) as each node or node data is stored in a list/collection to be returned |
153 | | -
|
154 | | - Returns: |
155 | | - List: list of nodes or node values/data traversed in inorder traversal fashion. |
156 | | - """ |
157 | | - |
158 | | - @abstractmethod |
159 | | - def is_balanced(self) -> bool: |
160 | | - """ |
161 | | - Checks if this tree is balanced. |
162 | | - A balanced tree is a tree where every node has 0 or more n children for n-ary trees or for binary trees, where |
163 | | - the heights of its left and right subtrees differ by at most 1 or 0 and both subtrees are also balanced. |
164 | | - @return: True if the tree is balanced, false otherwise |
165 | | - """ |
166 | | - raise NotImplementedError("This method has not yet been implemented") |
167 | | - |
168 | | - @abstractmethod |
169 | | - def leaf_similar(self, other: "Tree") -> bool: |
170 | | - """ |
171 | | - Returns true if this tree has similar leaf value sequence to another tree. |
172 | | - For example: If this tree has nodes = [3,5,1,6,2,9,8,null,null,7,4] and other tree has nodes = |
173 | | - [3,5,1,6,7,4,2,null,null,null,null,null,null,9,8]. Then the leaf value sequence of both is [6,7,4,9,8] which is |
174 | | - similar |
175 | | - @param other: Other tree |
176 | | - @return: True if the sequence of both tree's leaves is similar, false otherwise |
177 | | - """ |
178 | | - raise NotImplementedError("not yet implemented") |
179 | | - |
180 | | - @abstractmethod |
181 | | - def number_of_good_nodes(self) -> int: |
182 | | - """ |
183 | | - Finds the number of good nodes in a tree. A good node is a node in which in the path from root to the node there |
184 | | - are no nodes with a value greater than it |
185 | | - @return: The number of good nodes |
186 | | - """ |
187 | | - raise NotImplementedError("not yet implemented") |
188 | | - |
189 | | - @abstractmethod |
190 | | - def path_sum(self, target: T) -> int: |
191 | | - """Returns the number of paths where the sum of the values along the path equals target |
192 | | -
|
193 | | - Args: |
194 | | - target (T): The target that the sum of values along the path must equal |
195 | | -
|
196 | | - Returns: |
197 | | - int: The number of paths along which the values equal the target |
198 | | - """ |
199 | | - raise NotImplementedError("not yet implemented") |
200 | | - |
201 | | - @abstractmethod |
202 | | - def paths_to_target(self, target: T) -> List[T]: |
203 | | - """Returns the paths where the sum of the values along the path equals to the given target |
204 | | -
|
205 | | - Args: |
206 | | - target (T): The target that the sum of values along the path must equal |
207 | | -
|
208 | | - Returns: |
209 | | - list: The paths along which the values equal the target |
210 | | - """ |
211 | | - raise NotImplementedError("not yet implemented") |
212 | | - |
213 | | - def max_level_sum(self) -> int: |
214 | | - """Returns the smallest level x such that the sum of all the values of nodes at level x is maximal |
215 | | -
|
216 | | - Returns: |
217 | | - int: maximum value at level x |
218 | | - """ |
219 | | - raise NotImplementedError("not yet implemented") |
220 | | - |
221 | | - @abstractmethod |
222 | | - def serialize(self) -> str: |
223 | | - """Serializes a tree into a string |
224 | | - Returns: |
225 | | - str: string representation of tree. |
226 | | - """ |
227 | | - raise NotImplementedError("not yet implemented") |
228 | | - |
229 | | - @staticmethod |
230 | | - def deserialize(tree_str: str) -> "Tree": |
231 | | - """Serializes a tree into a string |
232 | | - Args: |
233 | | - tree_str (str): string representation of tree |
234 | | - Returns: |
235 | | - Tree: Tree deserialized from string |
236 | | - """ |
237 | | - raise NotImplementedError("not yet implemented") |
| 4 | +__all__ = ["Tree", "TreeNode", "BinaryTree", "BinaryTreeNode"] |
0 commit comments