Skip to content

Commit

Permalink
Merge pull request #36 from chrisyo99/master
Browse files Browse the repository at this point in the history
Added DataStructs and Algorithms folder for issue #24
  • Loading branch information
amandp13 authored Oct 23, 2020
2 parents 3e63b53 + 90e978b commit c4b645b
Show file tree
Hide file tree
Showing 4 changed files with 417 additions and 0 deletions.
193 changes: 193 additions & 0 deletions DataStructs and Algorithms/BinaryTree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import Stacks_Queue

class TreeNode():
def __init__(self, inKey, inValue):
self._key = inKey
self._value = inValue
self._left = None
self._right = None

def __str__(self):
return ("Key:" + str(self._key) + " Value: " + str(self._value))

class BinarySearchTree():
def __init__(self):
self._root = None

def _findRec(self, key, cur):
value = None
if cur == None:
raise ValueError("Key " + key + " not found")
elif key == cur._key:
value = cur._value
elif key < cur._key:
value = self._findRec(key, cur._left)
else:
value = self._findRec(key, cur._right)
return value

def find(self, key):
return self._findRec(key, self._root)

def _insertRec(self, key, cur, value):
if key < cur._key:
if cur._left == None:
cur._left = TreeNode(key, value)
else:
self._insertRec(key, cur._left, value)
elif key > cur._key:
if cur._right == None:
cur._right = TreeNode(key, value)
else:
self._insertRec(key, cur._right, value)

def insert(self, key, value):
#if exception is raised it means that the key is not yet in the tree
if self._root == None:
self._root = TreeNode(key, value)
else:
try:
self.find(key)
raise ValueError("Key " + key + " already exists in tree")
except:
self._insertRec(key, self._root, value)
#The delete functions
def _promoteSuccessor(self, curNode):
successor = curNode

if curNode._left == None:
successor = curNode
else:
if curNode._left != None:
successor = self._promoteSuccessor(curNode._left)
if successor == curNode._left:
curNode._left = successor._right
return successor

def _deleteNode(self, key, delNode):
updateNode = None

if delNode._left == None and delNode._right == None:
updateNode = None
elif delNode._left != None and delNode._right == None:
updateNode = delNode._left
elif delNode._left == None and delNode._right != None:
updateNode = delNode._right
else:
updateNode = self._promoteSuccessor(delNode._right)
if updateNode != delNode._right:
updateNode._right = delNode._right
updateNode._left = delNode._left
return updateNode


def _deleteRec(self, key, curNode):
updateNode = curNode
if curNode == None:
raise Exception("oh no")
elif key == curNode._key:
updateNode = self._deleteNode(key, curNode)
elif key < curNode._key:
curNode._left = self._deleteRec(key, curNode._left)
else:
curNode._right = self._deleteRec(key, curNode._right)

return updateNode

def delete(self, key):
self._deleteRec(key, self._root)

#All other methods for inormation on the tree
def _preorderRec(self, cur, resultQueue):
resultQueue.enqueue(cur)
if cur._left is not None:
self._preorderRec(cur._left, resultQueue)
if cur._right is not None:
self._preorderRec(cur._right, resultQueue)

def _inorderRec(self, cur, resultQueue):
if cur._left is not None:
self._inorderRec(cur._left, resultQueue)
resultQueue.enqueue(cur)
if cur._right is not None:
self._inorderRec(cur._right, resultQueue)

def _postorderRec(self, cur, resultQueue):
if cur._left is not None:
self._postorderRec(cur._left, resultQueue)
if cur._right is not None:
self._postorderRec(cur._right, resultQueue)
resultQueue.enqueue(cur)

def display(self, order = 'preorder', string = False):
resultQueue = Stacks_Queue.Queue()
result = ''
cur = self._root
if order == 'preorder':
self._preorderRec(cur, resultQueue)
elif order == 'inorder':
self._inorderRec(cur, resultQueue)
elif order == 'postorder':
self._postorderRec(cur, resultQueue)

if string == True:
empty = resultQueue.isEmpty()
while not empty:
temp = resultQueue.dequeue()
result = result + temp.__str__() + '\n'
empty = resultQueue.isEmpty()
resultQueue = result
return resultQueue


def _heightRec(self, curNode):
if curNode == None:
height = -1
else:
leftHeight = self._heightRec(curNode._left)
rightHeight = self._heightRec(curNode._right)

# Get highest of left vs right branches
if leftHeight > rightHeight:
height = leftHeight + 1
else:
height = rightHeight + 1
return height

def height(self):
return self._heightRec(self._root)

def _minRec(self, curNode):
if curNode._left != None:
minKey = self._minRec(curNode._left)
else:
minKey = curNode._key
return minKey

def min(self):
return self._minRec(self._root)

def max(self):
return self._root._key

def _balanceRec(self, curNode):
if curNode == None:
result = 0
else:
result = self._heightRec(curNode)

return result

def balance(self):
#base case No children at root
if self._root == None:
result = 100
else:
leftHeight = self._balanceRec(self._root._left)
rightHeight = self._balanceRec(self._root._right)

if leftHeight > rightHeight:
result = rightHeight/leftHeight *100
else:
result = leftHeight/rightHeight *100
return result
87 changes: 87 additions & 0 deletions DataStructs and Algorithms/LinkList.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
class ListNode():
def __init__(self, data = None):
self.next = None
self.prev = None
self.data = data

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

def isEmpty(self):
result = False
if self.head is None:
result = True
return result

def peekFirst(self):
return self.head.data

def peekLast(self):
return self.tail.data

def insertFirst(self, data = None):
node = ListNode(data)
if self.head is None:
self.head = node
self.tail = node
else:
temp = self.head
self.head = node
#then update listnodes pointers
self.head.next = temp
temp.prev = node

def insertLast(self, data = None):
node = ListNode(data)
if self.head is None:
self.head = node
self.tail = node
else:
temp = self.tail
self.tail = node
#then update listnodes pointers
self.tail.prev = temp
temp.next = node

def printList(self):
point = self.head
while(point is not None):
print(point.data)
point = point.next

def removeFirst(self):
temp = None
if self.isEmpty():
raise TypeError("List is Empty, cannot remove First")
elif self.head.next is None: #if there is only one item in list
temp = self.head.data
self.head = None
self.tail = None
else:
temp = self.head.data
self.head = self.head.next
self.head.prev = None
return temp

def removeLast(self):
temp = None
if self.isEmpty():
raise TypeError("List is Empty, cannot remove Last")
elif self.head.next is None: #if there is only one item in list
temp = self.head.data
self.head = None
self.tail = None
else:
temp = self.tail.data
self.tail = self.tail.prev
self.tail.next = None
return temp

#Iterator Functions
def __iter__(self):
currNode = self.head
while currNode is not None:
yield currNode.data
currNode = currNode.next
86 changes: 86 additions & 0 deletions DataStructs and Algorithms/Stacks_Queue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from LinkList import LinkedList

class Stack():
def __init__(self, size = 100):
self.size = size
self.stack = LinkedList()
self.count = 0


def getCount(self):
return self.count

def isEmpty(self):
result = False
if self.count == 0:
result = True
return result

def isFull(self):
result = False
if self.count == self.size:
result = True
return result

def push(self, value):
if self.isFull():
raise IndexError("Cannot push, size of stack is full")
else:
#print(self.stack)
self.stack.insertLast(value)
self.count = self.count + 1

def pop(self):
topVal = self.top()
self.count = self.count - 1
self.stack.removeLast()
return topVal

def top(self):
if self.isEmpty():
raise IndexError("Stack is empty")
else:
topVal = self.stack.peekLast()
#topVal = self.stack[self.count - 1]
return topVal

class Queue():
def __init__(self, size = 100):
self.count = 0
self.size = size
self.queue = LinkedList()

def getCount(self):
return self.count

def isEmpty(self):
result = False
if self.count == 0:
result = True
return result

def isFull(self):
result = False
if self.count == self.size:
result = True
return result

def peek(self):
if self.isEmpty():
raise IndexError("Queue is empty")
else:
frontVal = self.queue.peekFirst()
return frontVal

def enqueue(self, value):
if self.isFull():
raise IndexError("Cannot enqueue, size of queue is full")
else:
#self.queue[self.count] = value
self.queue.insertLast(value)
self.count = self.count + 1

def dequeue(self):
frontVal = self.queue.removeFirst()
self.count = self.count - 1
return frontVal
Loading

0 comments on commit c4b645b

Please sign in to comment.