Skip to content

Commit

Permalink
Add Python algorithms and data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
joachmak authored and Xtrah committed Nov 21, 2020
1 parent 3f23b38 commit 3e60bb8
Show file tree
Hide file tree
Showing 25 changed files with 1,059 additions and 0 deletions.
122 changes: 122 additions & 0 deletions Python/Datastrukturer/BinarySearchTree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Binary search tree property: Left node is smaller than parent, right node is larger than parent
import random
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.parent = None

def __str__(self):
return str(self.key)

def __repr__(self):
return str(self.key)

class BinaryTree:

def __init__(self, root):
self.root = root

def inorder_tree_walk(self, root): # Writes all numbers in increasing order
if root is not None:
self.inorder_tree_walk(root.left)
print("Key: " + str(root.key) + ", left: " + str(root.left) + ", right: " + str(root.right) + ", parent: " + str(root.parent))
self.inorder_tree_walk(root.right)

def tree_minimum(self, root):
while root.left is not None:
root = root.left
return root

def tree_maximum(self, root):
while root.right is not None:
root = root.right
return root

def tree_search(self, root, key):
while root is not None and key is not root.key:
if key < root.key:
root = root.left
else:
root = root.right
return root

def tree_successor(self, node): # Returns the node with the bigger key than the argument node
if node.right is not None:
return self.tree_minimum(node.right)
p = node.parent
while p is not None and node is p.right:
# "Go up one level"
node = p
p = p.parent
return p


def insert(self, T, node):
y = None
root = T.root
while root is not None:
y = root
if node.key < root.key:
root = root.left
else:
root = root.right
node.parent = y
if y is None: # The new node is the root
T.root = node
elif node.key < y.key:
y.left = node
else:
y.right = node

def transplant(self, T, u, v): # Replaces subtree rooted at u with subtree rooted at v
if u.parent == None:
T.root = v
elif u == u.parent.left:
u.parent.left = v
else:
u.parent.right = v
if v is not None:
v.parent = u.parent

def delete(self, T, node):
if node.left is None:
self.transplant(T,node,node.right) # Swap out subtree rooted at node with subtree rooted at node.right
elif node.right is None:
self.transplant(T, node, node.left) # Swap out subtree rooted at node with subtree rooted at node.right
else:
y = self.tree_minimum(node.right)
if y.parent != node:
self.transplant(T,y,y.right)
y.right = node.right
y.right.parent = y
self.transplant(T,node,y)
y.left = node.left
y.left.parent = y








rootNode = Node(5)
binTree = BinaryTree(rootNode)
nodeList = [rootNode]
for i in range(5):
n = Node(random.randint(-10,10))
nodeList.append(n)
binTree.insert(binTree, n)


print(nodeList)
print("Before:")
binTree.inorder_tree_walk(binTree.root)
print("\n")
print("After:")
print(type(nodeList[0]))
binTree.delete(binTree,nodeList[0])
binTree.inorder_tree_walk(binTree.root)

55 changes: 55 additions & 0 deletions Python/Datastrukturer/DirectAccessTable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class Node:
def __init__(self, key, satellite_data):
self.key = key
self.satellite_data = satellite_data

def __str__(self):
return str(self.key) + " : " + str(self.satellite_data)

class DirectAccessTable:

def __init__(self):
self.T = [None]*1000

def direct_address_search(self, k):
if len(self.T) > k:
return self.T[k]
return None

def direct_address_insert(self, x):
if len(self.T) < x.key:
self.T = self.T + [None]*1000 # expand table
self.T[x.key] = x

def direct_address_delete(self, x):
if len(self.T) < x.key:
return
self.T[x.key] = None

def __str__(self):
result = "PRINTING ["
for node in range(len(self.T)):
if node != None:
result += str(self.T[node]) + ", "
else:
result += "None, "
return result + "]"


a = Node(2, [1,5,3,2])
b = Node(3, [2,3,69])
c = Node(10, [69,420])

dat = DirectAccessTable()

dat.direct_address_insert(a)
dat.direct_address_insert(b)
print(str(dat))
dat.direct_address_insert(c)

print(dat.direct_address_search(b.key))
dat.direct_address_delete(b)
print(dat.direct_address_search(b.key))
print(str(dat))


56 changes: 56 additions & 0 deletions Python/Datastrukturer/HashTable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import Python.Datastrukturer.LinkedList as LL
import random
import math
class HashTable:

def __init__(self):
self.T = []
for i in range(10):
self.T.append(LL.LSingly())

def hash_search(self, k):
hashKey = self.hash_function(k)
if hashKey > len(self.T):
return None
return self.T[hashKey].list_search(k)

def hash_insert(self, x):
hashKey = self.hash_function(x.key)
while len(self.T) < hashKey+1: # TODO: Use Table-insert instead of this (p 464)
self.T.append(LL.LSingly())
self.T[hashKey].list_insert(x)

def hash_delete(self, x):
hashKey = self.hash_function(x.key)
if len(self.T) < hashKey:
return
self.T[hashKey].list_delete(x)

def hash_function(self, key): # TODO: Modify dis
A = (math.sqrt(5) - 1)/2
m = 2**5
b = (key*A) % 1
return math.floor(m*b)

def __str__(self):
result = "["
for node in self.T:
result += str(node) + ","
result += "]\n Fordeling: ["
for node in self.T:
result += str(node.list_length()) + ","
result += "]"
return result




for i in range(3000): # reliability testing
ht = HashTable();
for j in range(1000):
a = LL.Node(random.randint(0,100))
ht.hash_insert(a)

print("\n\n" + str(ht))

ht.hash_delete(a)
71 changes: 71 additions & 0 deletions Python/Datastrukturer/Heap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from Python.Datastrukturer.HeapList import HeapList as HL
import random

def exchange(A, idx_A, idx_B):
temp = A[idx_A]
A[idx_A] = A[idx_B]
A[idx_B] = temp
return A

def parent(i):
return i // 2


def left(i):
return 2 * i


def right(i):
return (2 * i) + 1

def build_max_heap(A): # O(n*lg(n))) produces a max-heap from an unordered array
for i in range(A.heapsize//2, -1, -1): # n/2
A = max_heapify(A, i)
return A

# Max heap property: A[parent(i)] >= A[i], largest element is the root
# Min heap property: A[parent(i)] <= A[i], smallest element is the root
# Height of a heap: θ(lg n)

def max_heapify(A, idx): # O(lg n), helps maintain the max-heap property
if A[0] is not None:
A.addNone()
idx += 1
leftIdx = left(idx)
rightIdx = right(idx)
largest = idx
if leftIdx < A.heapsize and A[leftIdx] > A[largest]: # if the left child is larger than its parent
largest = leftIdx
if rightIdx < A.heapsize and A[rightIdx] > A[largest]: # if the right child is the largest
largest = rightIdx
if largest != idx: # if the parent is not the largest
A = exchange(A, idx, largest) # Exchange the parent with the largest element
A = max_heapify(A, largest) # Check if the element should be placed lower down
if A[0] is None:
A.removeNone()
return A


def heapsort(A):
A = build_max_heap(A) # n lg(n)
for i in range(len(A.getArr())-1,0,-1): # n
A = exchange(A, 0, i)
A.reduceHeapSize()
A = max_heapify(A,0) # lg n
return A

arr = [1,1,2,6,39]
heap = HL(arr, len(arr))
heap = build_max_heap(heap)
#print(heap)

for i in range(10):
heap.addInFront(random.randint(-100,100))
heap = max_heapify(heap,0)

#print(heap)

arr = [3,2,6,19,2,3,-1,-53,2,4,5.34,-123]
testHeap = HL(arr, len(arr))
print(heapsort(testHeap))

33 changes: 33 additions & 0 deletions Python/Datastrukturer/HeapList.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@


class HeapList:
def __init__(self, arr, heapsize):
self.arr = arr
self.heapsize = heapsize

def __str__(self):
return str(self.arr)

def __getitem__(self, item):
return self.arr[item]

def __setitem__(self, key, value):
self.arr[key] = value

def addNone(self):
self.arr = [None] + self.arr
self.heapsize += 1

def removeNone(self):
self.arr = self.arr[1:]
self.heapsize -= 1

def addInFront(self, value):
self.arr = [value] + self.arr
self.heapsize += 1

def reduceHeapSize(self):
self.heapsize -= 1

def getArr(self):
return self.arr
Loading

0 comments on commit 3e60bb8

Please sign in to comment.