Skip to content

Ivette F. - Spruce #49

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 118 additions & 19 deletions binary_search_tree/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,135 @@ class Tree:
def __init__(self):
self.root = None

# Time Complexity:
# Space Complexity:
# Time Complexity: O(log(n))
# Space Complexity: O(1)
Comment on lines +17 to +18

Choose a reason for hiding this comment

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

def add(self, key, value = None):
pass
added_node = TreeNode(key, value)
if not self.root:
self.root = added_node
return self.root
parent_node = self.root
while True:

Choose a reason for hiding this comment

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

Generally try to avoid having while loop conditions that can never be Falsey. You always want to be making progress towards make the loop condition False in the loop body.

How might you refactor your code to eliminate the while True. (Hint: look at your find implementation)

# if the added_node is greater than the parent_node
if added_node.key > parent_node.key:
# if the parent_node does NOT have a right node
if not parent_node.right:
parent_node.right = added_node
return added_node
# if the parent_node DOES have a right node, make its right node the new parent_node
else:
parent_node = parent_node.right
# if the added_node is less than the parent_node
elif added_node.key <= parent_node.key:
# if the parent_node does NOT have a left node
if not parent_node.left:
parent_node.left = added_node
return added_node
# if the parent_node DOES have a left node, make its left node the new parent_node
else:
parent_node = parent_node.left
else:
return "WTF"

Choose a reason for hiding this comment

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

🤯
You could remove this line and leave line 36 as an else (or as is)



# Time Complexity:
# Space Complexity:
# Time Complexity: O(log(n))
# Space Complexity: O(1)
def find(self, key):

Choose a reason for hiding this comment

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

✨ Nice iterative solution

pass
current_node = self.root
while current_node:
if key == current_node.key:
return current_node.value
elif key > current_node.key:
current_node = current_node.right
elif key < current_node.key:
current_node = current_node.left
return None

# left, current, right
def inorder_helper(self, current_node, node_list = None):

Choose a reason for hiding this comment

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

if node_list == None:
node_list = []
if current_node:
self.inorder_helper(current_node.left, node_list)
node_list.append({
"key" : current_node.key,
"value" : current_node.value,
})
self.inorder_helper(current_node.right, node_list)
return node_list

# Time Complexity:
# Space Complexity:
# Time Complexity: O(n)
# Space Complexity: O(n)
def inorder(self):

Choose a reason for hiding this comment

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

pass
return self.inorder_helper(self.root)

def preorder_helper(self, current_node, node_list = None):

Choose a reason for hiding this comment

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

if node_list == None:
node_list = []
if current_node:
node_list.append({
"key" : current_node.key,
"value" : current_node.value,
})
self.preorder_helper(current_node.left, node_list)
self.preorder_helper(current_node.right, node_list)
return node_list

# Time Complexity:
# Space Complexity:
# Time Complexity: O(n)
# Space Complexity: O(n)
def preorder(self):

Choose a reason for hiding this comment

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

pass
return self.preorder_helper(self.root)

# Time Complexity:
# Space Complexity:
def postorder_helper(self, current_node, node_list = None):

Choose a reason for hiding this comment

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

if node_list == None:
node_list = []
if current_node:
self.postorder_helper(current_node.left, node_list)
self.postorder_helper(current_node.right, node_list)
node_list.append({
"key" : current_node.key,
"value" : current_node.value,
})
return node_list

# Time Complexity: O(n)
# Space Complexity: O(n)
def postorder(self):

Choose a reason for hiding this comment

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

pass
return self.postorder_helper(self.root)

# Time Complexity:
# Space Complexity:
def height(self):
pass
def height_helper(self, current_node, node_list = None):
if node_list == None:
node_list = []
if current_node:
self.height_helper(current_node.left, node_list)
if current_node.left == None and current_node.right == None:
node_list.append(current_node.key)
self.height_helper(current_node.right, node_list)
return node_list

def find_count(self, key):
current_node = self.root
count = 0
while current_node:
count += 1
if key == current_node.key:
return count
elif key > current_node.key:
current_node = current_node.right
elif key < current_node.key:
current_node = current_node.left
return None

# Time Complexity: O(nlog(n))
# Space Complexity: O(m) where m is the number of end nodes
Comment on lines +136 to +137

Choose a reason for hiding this comment

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

✨ This time and space complexity is correct for your solution!

You could refactor your code to achieve an O(n) time and space solution. Instead of having height_helper return a list, have it return an integer. When you make a recursive call on the left/right subtree, you know that your height is 1 + the height of the deepest subtree. So you can say that the height is 1 + max(height of left subtree, height of right subtree).

def height(self):
ends_list = self.height_helper(self.root)
max_height = 0
for end_key in ends_list:
height = self.find_count(end_key)
if height > max_height:
max_height = height
return max_height

# # Optional Method
# # Time Complexity:
Expand Down