Skip to content

Patrick de vincentis #750

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 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
159 changes: 145 additions & 14 deletions binary_search_tree/binary_search_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,168 @@ def __init__(self, value):

# Insert the given value into the tree
def insert(self, value):
pass
# check if the new nodes value is less than the current nodes value
if value < self.value:
# if there is no left child already here
# add the new node to the left
# create a BSTNode and encapsulate the value in it then set it to the left
if self.left == None:
self.left = BSTNode(value)

# otherwise call insert on the left node
else:
self.left.insert(value)

# otherwise (the new nodes value is greaterthan or equal to the current node value)
elif value >= self.value:
# if there is no right child already here
if not self.right:
# add the new node to the right
# create a BSTNode and encapsulate the value in it then set it to the right
self.right = BSTNode(value)
else:
# otherwise call insert on the right node
self.right.insert(value)


# Return True if the tree contains the value
# False if it does not
def contains(self, target):
pass

# if the value of the current node matches the target
if self.value == target:
# return True
return True
# check if the target is less than the current nodes value
if self.value > target:
# if there is no left child already here
if not self.left:
return False
# return False
else:
# otherwise
return self.left.contains(target)
# return a call of contains on the left child passing in the target value

# otherwise (the target is greater than the current nodes value)
else:

# if there is no right child already here
if not self.right:
# return False
return False
# otherwise
else:
# return a call of contains on the right child passing in the target value
return self.right.contains(target)



# Return the maximum value found in the tree
def get_max(self):
pass

if not self.value:
return None
# check for an empty tree
# return None

# ----------------------------------------------
# recursive approach
# check if there is no node to the right
elif not self.right:
return self.value
# return the nodes value
# return a call to get max on the right child
return self.right.get_max()
# -----------------------------------------------

# iterative aproach

# initialise the max value

# get a ref to the current node

# loop while there is still a current node
# if the current value is greater than the max value, update the max value
# move on to the next right node

# return the max value


# Call the function `fn` on the value of each node
def for_each(self, fn):
pass
# call the function passing in the current nodes value
fn(self.value)

# if there is a node to the left
if self.left:
self.left.for_each(fn)
# call the function on the left value

# if there is a node to the right
if self.right:
self.right.for_each(fn)
# call the function on the right node






# Part 2 -----------------------

# Print all the values in order from low to high
# Hint: Use a recursive, depth first traversal
def in_order_print(self):
pass
print(self.value)
if self.left:
self.left.in_order_print()
if self.right:
self.right.in_order_print()

# Print the value of every node, starting with the given node,
# in an iterative breadth first traversal
def bft_print(self):
pass
# Create an empty queue
# add root value to queue
# while there are items in the queue do the following
# go to first item in the queue
# if there is a left value add it
# if there is a right value add it
# print the item in the queue that you are on and dequeue it.

newQueue = []
newQueue.append(self)
while len(newQueue):
current = newQueue.pop(0)
print(current.value)
if current.left:
newQueue.append(current.left)
if current.right:
newQueue.append(current.right)


# Print the value of every node, starting with the given node,
# in an iterative depth first traversal
def dft_print(self):
pass
# Create an empty stack
# add root value to stack
# while there are items in the stack do the following
# go to last item in the stack
# if there is a left value add it
# if there is a right value add it
# print the item in the stack that you are on and dequeue it.

stack = []
stack.append(self)
while len(stack):
current = stack.pop()
print(current.value)
if current.right:
stack.append(current.right)
if current.left:
stack.append(current.left)


# Stretch Goals -------------------------
# Note: Research may be required
Expand Down Expand Up @@ -76,10 +207,10 @@ def post_order_dft(self):
bst.bft_print()
bst.dft_print()

print("elegant methods")
print("pre order")
bst.pre_order_dft()
print("in order")
bst.in_order_dft()
print("post order")
bst.post_order_dft()
# print("elegant methods")
# print("pre order")
# bst.pre_order_dft()
# print("in order")
# bst.in_order_dft()
# print("post order")
# bst.post_order_dft()
98 changes: 90 additions & 8 deletions doubly_linked_list/doubly_linked_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,56 +27,138 @@ def __len__(self):
the old head node's previous pointer accordingly.
"""
def add_to_head(self, value):
pass
# wrap the input value in a node
new_node = ListNode(value)
# increment the length
self.length += 1
# check if the linked list is empty
if not self.head and not self.tail:
# if the list is initially empty, set both head and tail to the new node
self.head = new_node
self.tail = new_node
# we have a non-empty list, add the new node to the head
else:
# set the new node's `next` to refer to the current head
new_node.next = self.head
# set the current head's 'prev' to refer to the new_node (added to make it work with DLL)
self.head.prev = new_node
# set the list's head reference to the new node
self.head = new_node

"""
Removes the List's current head node, making the
current head's next node the new head of the List.
Returns the value of the removed Node.
"""
def remove_from_head(self):
pass
value = self.head.value
self.delete(self.head)
return value

"""
Wraps the given value in a ListNode and inserts it
as the new tail of the list. Don't forget to handle
the old tail node's next pointer accordingly.
"""
def add_to_tail(self, value):
pass
new_node = ListNode(value, None, None)
self.length += 1
if not self.tail and not self.head:
self.tail = new_node
self.head = new_node
else:
new_node.prev = self.tail
self.tail.next = new_node
self.tail = new_node

"""
Removes the List's current tail node, making the
current tail's previous node the new tail of the List.
Returns the value of the removed Node.
"""
def remove_from_tail(self):
pass
value = self.tail.value
self.delete(self.tail)
return value

"""
Removes the input node from its current spot in the
List and inserts it as the new head node of the List.
"""
def move_to_front(self, node):
pass
if node is self.head:
return
value = node.value
if node is self.tail:
self.remove_from_tail()
else:
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev

self.length -= 1
self.add_to_head(value)

"""
Removes the input node from its current spot in the
List and inserts it as the new tail node of the List.
"""
def move_to_end(self, node):
pass
if node is self.tail:
return
value = node.value
if node is self.head:
self.remove_from_head()
else:
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev

self.length -= 1
self.add_to_tail(value)

"""
Deletes the input node from the List, preserving the
order of the other elements of the List.
"""
def delete(self, node):
pass
if not self.head and not self.tail:
return
if self.head is self.tail:
self.head = None
self.tail = None
elif self.head is node:
self.head = node.next
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev
elif self.tail is node:
self.tail = node.prev
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev
else:
if node.prev:
node.prev.next = node.next
if node.next:
node.next.prev = node.prev
self.length -= 1

"""
Finds and returns the maximum value of all the nodes
in the List.
"""
def get_max(self):
pass
if not self.head:
return None
max_val = self.head.value
current = self.head
while current:
if current.value > max_val:
max_val = current.value
current = current.next
return max_val
41 changes: 36 additions & 5 deletions queue/queue.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import sys

sys.path.append("../singly_linked_list")
from singly_linked_list import LinkedList

"""
A queue is a data structure whose primary purpose is to store and
return elements in First In First Out order.
Expand All @@ -13,16 +18,42 @@
Stretch: What if you could only use instances of your Stack class to implement the Queue?
What would that look like? How many Stacks would you need? Try it!
"""
class Queue:
class QueueArray:
def __init__(self):
self.size = 0
# self.storage = ?
self.storage = []

def __len__(self):
pass
return len(self.storage)

def enqueue(self, value):
pass
self.storage.insert(0, value)

def dequeue(self):
pass
if len(self.storage) == 0:
return None
else:
self.storage.pop()




class Queue:
def __init__(self):
self.size = 0
self.storage = LinkedList()

def __len__(self):
return self.storage.size()

def enqueue(self, value):
self.storage.add_to_tail(value)
self.size +=1

def dequeue(self):
if self.storage.size == 0:
return None
else:
popped = self.storage.remove_head()
self.size -=1
return popped
Loading