From 0e1a9eb058cb87124fd0c2784712028ee08a07c2 Mon Sep 17 00:00:00 2001 From: Aida Date: Wed, 29 Dec 2021 00:31:51 -0800 Subject: [PATCH] Add methods to Tree class --- binary_search_tree/tree.py | 140 +++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 23 deletions(-) diff --git a/binary_search_tree/tree.py b/binary_search_tree/tree.py index cdd5abc..79bfb8d 100644 --- a/binary_search_tree/tree.py +++ b/binary_search_tree/tree.py @@ -14,45 +14,139 @@ class Tree: def __init__(self): self.root = None - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) if Balanced BST and O(n) for Unbalanced BST + # Space Complexity: O(log n) if Balanced BST and O(1) for Unbalanced BST + def add_helper(self, current_node, key, value): + if current_node == None: + return TreeNode(key, value) + if current_node.key >= key: + current_node.left = self.add_helper(current_node.left, key, value) + elif current_node.key < key: + current_node.right = self.add_helper(current_node.right, key, value) + return current_node + def add(self, key, value = None): - pass + if self.root == None: + self.root = TreeNode(key, value) + else: + self.add_helper(self.root, key, value) + + # Time Complexity: O(log n) if Balanced BST and O(n) for Unbalanced BST + # Space Complexity: O(log n) if Balanced BST and O(1) for Unbalanced BST + def find_helper(self, current, key): + if current == None: + return None + if key == current.key: + return current.value + elif key < current.key and current.left != None: + return self.find_helper(current.left, key) + elif key > current.key and current.right != None: + return self.find_helper(current.right, key) - # Time Complexity: - # Space Complexity: def find(self, key): - pass + if self.root != None: + return self.find_helper(self.root, key) + + # Time Complexity: O(n) where n is each visited node + # Space Complexity: O(n) - O(h) for the call stack, where h is the height of the tree + # Inorder Traversal: Left - Root - Right + def inorder_helper(self, current, ascending_nodes): + if current == None: + return None + + self.inorder_helper(current.left, ascending_nodes) + ascending_nodes.append({"key": current.key, + "value": current.value}) + self.inorder_helper(current.right, ascending_nodes) - # Time Complexity: - # Space Complexity: def inorder(self): - pass + if self.root == None: + return [] + + ascending_nodes = [] + self.inorder_helper(self.root, ascending_nodes) + + return ascending_nodes + + # Time Complexity: O(n) where n is each visited node + # Space Complexity: O(n) - O(h) for the call stack, where h is the height of the tree + # Preoder traversal: Root - Left - Right + def preorder_helper(self, current, preorder_nodes): + if current == None: + return None + + preorder_nodes.append({"key": current.key, + "value": current.value}) + self.preorder_helper(current.left, preorder_nodes) + self.preorder_helper(current.right, preorder_nodes) - # Time Complexity: - # Space Complexity: def preorder(self): - pass + if self.root == None: + return [] + + preorder_nodes = [] + self.preorder_helper(self.root, preorder_nodes) + + return preorder_nodes + + # Time Complexity: O(n) where n is each visited node + # Space Complexity: O(n) - O(h) for the call stack, where h is the height of the tree + # Postorder traversal: Left - Right - Root + def postorder_helper(self, current, postorder_nodes): + if current == None: + return None + + self.postorder_helper(current.left, postorder_nodes) + self.postorder_helper(current.right, postorder_nodes) + postorder_nodes.append({"key": current.key, + "value": current.value}) - # Time Complexity: - # Space Complexity: def postorder(self): - pass + if self.root == None: + return [] - # Time Complexity: - # Space Complexity: - def height(self): - pass + postorder_nodes = [] + self.postorder_helper(self.root, postorder_nodes) + + return postorder_nodes + + # Time Complexity: O(log n) if Balanced BST and O(n) for Unbalanced BST + # Space Complexity: O(n) where n is the number of nodes in a given binary tree. + def height_helper(self, current, current_height): + if current == None: + return current_height + left_height = self.height_helper(current.left, current_height + 1) + right_height = self.height_helper(current.right, current_height + 1) + + return max(left_height, right_height) + + def height(self): + if self.root != None: + return self.height_helper(self.root, 0) + else: + return 0 # # Optional Method -# # Time Complexity: -# # Space Complexity: +# # Time Complexity: O(n) where n is the number of nodes -1 except root +# # Space Complexity: O(?) def bfs(self): - pass + if self.root == None: + return [] - + level_nodes = [] + queue = [self.root] + + while len(queue) > 0: + current = queue.pop(0) + if current.left: + queue.append(current.left) + if current.right: + queue.append(current.right) + level_nodes.append({"key": current.key, + "value": current.value}) + return level_nodes # # Useful for printing def to_s(self):