Skip to content
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
35 changes: 35 additions & 0 deletions names/binary_search_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class BinarySearchTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.count = 1

''' Insert given value into tree . If no Node , insert new node . If Node , implement recursion . '''

''' If tree contains value , return TRUE . Return False otherwise . '''

def insert(self, value):
if value < self.value:
if not self.left:
self.left = BinarySearchTree(value)
else:
self.left.insert(value)
else:
if not self.right:
self.right = BinarySearchTree(value)
else:
self.right.insert(value)

''' Implement recursion '''
def contains(self, target):
if target == self.value:
return True
elif target < self.value:
if self.left is None:
return False
return self.left.contains(target)
else:
if self.right is None:
return False
return self.right.contains(target)
21 changes: 19 additions & 2 deletions names/names.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
import time
# Import Binary Search
from binary_search_tree import BinarySearchTree

start_time = time.time()

f = open('names_1.txt', 'r')
f = open('names/names_1.txt', 'r')
names_1 = f.read().split("\n") # List containing 10000 names
f.close()

f = open('names_2.txt', 'r')
f = open('names/names_2.txt', 'r')
names_2 = f.read().split("\n") # List containing 10000 names
f.close()

duplicates = [] # Return the list of duplicates in this data structure

# Replace the nested for loops below with your improvements
'''
for name_1 in names_1:
for name_2 in names_2:
if name_1 == name_2:
duplicates.append(name_1)
'''
# Above takes roughly 7 secs - 0(n^2)

# Starting in middle of alphabet
bst = BinarySearchTree('N')

for name in names_1:
bst.insert(name)

for name in names_2:
if bst.contains(name):
duplicates.append(name)

#BST method runtime: 0.1453089714050293 seconds - 0(n * log(n))

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
Expand Down
36 changes: 28 additions & 8 deletions reverse/reverse.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
class Node:
def __init__(self, value=None, next_node=None):
self.value = value
self.next_node = next_node
'''Holds Node value'''
self.value = value
'''references nxt Node'''
self.next_node = next_node

def get_value(self):
return self.value
Expand All @@ -10,11 +12,13 @@ def get_next(self):
return self.next_node

def set_next(self, new_next):
self.next_node = new_next
'''sets nxt Node refrence to whatever Node is passed in'''
self.next_node = new_next

class LinkedList:
def __init__(self):
self.head = None
''' Head '''
self.head = None

def add_to_head(self, value):
node = Node(value)
Expand All @@ -28,15 +32,31 @@ def contains(self, value):
if not self.head:
return False

current = self.head
'''Reference current Node , update as we iterate over list'''
current = self.head

while current:
if current.get_value() == value:
return True
'''Check if Node is valid , return True if Node value matches target value'''
return True

current = current.get_next()
'''update to point to next Node'''
current = current.get_next()

return False

def reverse_list(self, node, prev):
pass
if self.head is None:
return '...'
prev = None
cur = self.head
nxt = self.head.get_next()

while cur != None:
cur.set_next(prev)
prev = cur
cur = nxt
if nxt != None:
nxt = cur.get_next()

self.head = prev
138 changes: 138 additions & 0 deletions ring_buffer/doubly_linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"""Each ListNode holds a reference to its previous node
as well as its next node in the List."""


class ListNode:
def __init__(self, value, prev=None, next=None):
self.value = value
self.prev = prev
self.next = next

"""Wrap the given value in a ListNode and insert it
after this node. Note that this node could already
have a next node it is point to."""
def insert_after(self, value):
current_next = self.next
self.next = ListNode(value, self, current_next)
if current_next:
current_next.prev = self.next

"""Wrap the given value in a ListNode and insert it
before this node. Note that this node could already
have a previous node it is point to."""
def insert_before(self, value):
current_prev = self.prev
self.prev = ListNode(value, current_prev, self)
if current_prev:
current_prev.next = self.prev

"""Rearranges this ListNode's previous and next pointers
accordingly, effectively deleting this ListNode."""
def delete(self):
if self.prev:
self.prev.next = self.next
if self.next:
self.next.prev = self.prev


"""Our doubly-linked list class. It holds references to
the list's head and tail nodes."""


class DoublyLinkedList:
def __init__(self, node=None):
self.head = node
self.tail = node
self.length = 1 if node is not None else 0

def __len__(self):
return self.length

"""Wraps the given value in a ListNode and inserts it
as the new head of the list. Don't forget to handle
the old head node's previous pointer accordingly."""
def add_to_head(self, value):
new_node = ListNode(value, None, None)
self.length += 1
if not self.head and not self.tail:
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head.prev = 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):
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):
new_node = ListNode(value, None, None)
self.length += 1
if not self.head and not self.tail:
self.head = new_node
self.tail = 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):
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):
if node is self.head:
return
value = node.value
self.delete(node)
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):
if node is self.tail:
return
value = node.value
self.delete(node)
self.add_to_tail(value)

"""Removes a node from the list and handles cases where
the node was the head or the tail"""
def delete(self, node):
self.length -= 1
if self.head is self.tail:
self.head = None
self.tail = None
elif self.head is node:
self.head = node.next
node.delete()
elif self.tail is node:
self.tail = node.prev
node.delete()
else:
node.delete()

"""Returns the highest value currently in the list"""
def get_max(self):
max_value = self.head.value
current = self.head
while current is not None:
if current.value > max_value:
max_value = current.value
current = current.next

return max_value
40 changes: 40 additions & 0 deletions ring_buffer/ring_buffer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,44 @@
from doubly_linked_list import DoublyLinkedList

# Look to see whether list has reached full capacity
# if so - replace the current item with the new item
# move current item to next item in list
# if current item = tail, next value is head
# if not at capacity then add to end of storage
# if the storage had no items then set current item to new item
# add node data to list and move pointer

class RingBuffer:
def __init__(self, capacity):
self.capacity = capacity
self.current = None
self.storage = DoublyLinkedList()

def append(self, item):
if self.capacity == len(self.storage):
self.current.value = item
if self.current == self.storage.tail:
self.current = self.storage.head
else:
self.current = self.current.next
else:
self.storage.add_to_tail(item)
if len(self.storage) == 1:
self.current = self.storage.head

def get(self):
list_buffer_contents = []

node = self.storage.head
while node is not None:
list_buffer_contents.append(node.value)
node = node.next

return list_buffer_contents

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

class ArrayRingBuffer:
def __init__(self, capacity):
pass

Expand Down