Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gloria Scissors - Binary Trees #46

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
184 changes: 155 additions & 29 deletions binary_search_tree/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,183 @@ def __init__(self, key, val = None):
if val == None:
val = key

self.key = key
self.value = val
self.key = key
self.left = None
self.right = None



# self.val = key

class Tree:
def __init__(self):
def __init__(self, height = None):
self.root = None
self.nodes = []
#hold for the bfs
self.queque = []
# self.treeheight = 0
self.bfs_nodes = []

# Time Complexity:
# Space Complexity:
# Time Complexity: O(n) because looping through all the nodes
# Space Complexity: O(n) because you need to add a node for each key, value
def add(self, key, value = None):
Comment on lines +21 to 23

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 The time complexity is O(n log n ) if the tree is balanced and O(n) otherwise.

pass

if self.root == None:
self.root = TreeNode(key,value)
else:
parent = None
current = self.root
while (current !=None):
parent = current
if current.key > key:
current = current.left
else:
current = current.right
if parent.key > key:
parent.left = TreeNode(key,value)
else:
parent.right = TreeNode(key,value)


# Time Complexity:
# Space Complexity:
def create_dict(self, TreeNode):
return { "key": TreeNode.key,
"value": TreeNode.value }
Comment on lines +42 to +44

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful helper, maybe put this in the TreeNode class.



# Time Complexity: log(n) because we are examining only half of the nodes
# Space Complexity: O(1) because we are not allocating any memory
# self refers to object the class is making
def find(self, key):
Comment on lines +47 to 50

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 The time complexity is O(n log n ) if the tree is balanced and O(n) otherwise.

pass
if self.root == None:
return None

current = self.root
while current != None:
if current.key == key:
return current.value
elif current.key < key:
current = current.right
else:
current = current.left
return None


# Time Complexity: O(N). Since it is recursive it is O(N) because the stack size will depend on the input size. Behind the scenes a new stack frame is created to hold the return address and variables you create in the new call.
# Space Complexity: 0(N) depends on input size

# first go to left
# add to the list
# go to the right




def preorder_traverse(self, node, node_list):
node_list.append(self.create_dict(node))
if node.left!=None:
self.preorder_traverse(node.left, node_list)
if node.right!=None:
self.preorder_traverse(node.right, node_list)

def postorder_traverse(self, node, node_list):
if node.left!=None:
self.postorder_traverse(node.left, node_list)
if node.right!=None:
self.postorder_traverse(node.right, node_list)
node_list.append(self.create_dict(node))

# Time Complexity:
# Space Complexity:
def inorder_traverse(self, node, node_list):
if node.left!=None:
self.inorder_traverse(node.left, node_list)
node_list.append(self.create_dict(node))
if node.right!=None:
self.inorder_traverse(node.right, node_list)



def inorder(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Time/space complexity?

pass
node_list = []
if self.root == None:
return []
self.inorder_traverse(self.root, node_list)
return node_list

# Time Complexity:
# Space Complexity:
# Time Complexity: 0(N)
# Space Complexity: Space Complexity: 0(N) depends on input size
def preorder(self):
Comment on lines +105 to 107

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Time/space complexity?

pass
node_list = []

if self.root == None:
return []
self.preorder_traverse(self.root, node_list)
return node_list



# Time Complexity:
# Space Complexity:
# Time Complexity: 0(N)
# Space Complexity: 0(N) depends on input size
def postorder(self):
Comment on lines +117 to 119

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Time/space complexity?

pass
node_list = []

# Time Complexity:
# Space Complexity:
def height(self):
pass
if self.root == None:
return []
self.postorder_traverse(self.root, node_list)
return node_list


# Time Complexity: 0(1) constant time
# Space Complexity: 0(1)
def height(self):
Comment on lines +128 to +130

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 this is O(n) for time complexity and O(n) space complexity if the tree is unbalanced and O(log n) if the tree is balanced.

return self.height_helper(self.root)



def height_helper(self, current):

# Check if the binary tree is empty
if current is None:
# If TRUE return 0
return 0
# Recursively call height of each node
leftHeight = self.height_helper(current.left)
rightHeight = self.height_helper(current.right)
my_max = max(leftHeight, rightHeight)
# Return max(leftHeight, rightHeight) at each iteration
return my_max + 1



# # Optional Method
# # Time Complexity:
# # Space Complexity:
# # Time Complexity: O(N) goes through all the nodes
# # Space Complexity: O(N) all the nodes
# Create function processing root
# If null empty array
# Create a array use only the root then Loop
# Make an array empty but will contain dictionaries at end
# While que not empty
# Before pop head get info of current node add dict to the final array
# Encue the children insert at the tail
# https://www.geeksforgeeks.org/level-order-tree-traversal/
def bfs(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Nice work!

pass


if self.root is None:
return []
self.queque = [self.root]

while len(self.queque) > 0:
cur_node = self.queque.pop(0)
my_dict_of_current_node = self.create_dict(cur_node)
self.bfs_nodes.append(my_dict_of_current_node)

if cur_node.left is not None:
self.queque.append(cur_node.left)

if cur_node.right is not None:
self.queque.append(cur_node.right)

return self.bfs_nodes

# # Useful for printing
def to_s(self):
def to_str(self):
return f"{self.inorder()}"



Binary file modified tests/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
4 changes: 3 additions & 1 deletion tests/test_binary_search_tree.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
import pytest
from binary_search_tree.tree import Tree


Expand All @@ -22,6 +22,8 @@ def test_add_and_find(tree_with_nodes):
assert tree_with_nodes.find(15) == "Ada"
assert tree_with_nodes.find(3) == "Paul"

# return test_add_and_find

def test_find_returns_none_for_empty_tree(empty_tree):
assert empty_tree.find(5) == None

Expand Down