Python Datastructures
Collection of self-implemented datastructure with python, including a Queue, Stack, BST, Hashmap, LL, Heap...
Source code
Requirements
The datastructures can be used with any datatype.
Basic requirements for datatypes:
- Can be compared with == , < , > (Necessary only for the Binary Search Tree)
- Have a way to be displayed properly (for instance for classes through the __str__ method)
Datastructures:
- Stack
- Queue
- Double Ended Queue
- Dictionary / Associative Structure
- Linked List
- Binary Search Tree
- Hashmap
- Hashlist
- Heap = Priority Queue
For further reference, the Wikipedia list of some data structures:
https://en.wikipedia.org/wiki/List_of_data_structures
Documentation
Stack
https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
Stacks work with the LIFO system: Last In First Out.
from stack import*
s = Stack()
for loop in range(1,10):
s.push(loop)
print(s) #Works properly as long as elements in stack have __str__ method
while s.size() > 0:
print(s.pop()) #Numbers from 9 to 1
print(s.pop()) #None
Available methods:
- push(value) -> adds value to the end
- pop() -> returns last value and deletes it
- peek() -> returns last value
- size() -> returns size of stack
The constructor has to stay empty, no starting data needs to be passed.
Queue
https://en.wikipedia.org/wiki/Queue_(abstract_data_type)
Queues work with the FIFO system: First In First Out.
from queue import*
q = Queue()
for loop in range(1,10):
q.add(loop)
while q.size() > 0:
print(q.poll()) #Numbers from 1 to 9
print(q.peek()) #None
Available methods:
- add(value) -> adds value to the end
- poll() -> returns first value and deletes it
- peek() -> returns first value
- size() -> returns size of queue
The constructor has to stay empty, no starting data needs to be passed.
Double Ended Queue <=> DEQUEUE
https://en.wikipedia.org/wiki/Double-ended_queue
The Double Ended Queue is a mix of the stack and the queue and can therefore be used instead of those structures.
from dequeue import*
dq = Dequeue()
for loop in range(1,10):
dq.addLast(loop)
while dq.size() > 0:
print(dq.pollFirst()) #Numbers from 1 to 9
print(dq.pollFirst()) #None
Available methods:
- addFirst(value) -> adds value to the beginning
- addLast(value) -> adds value to the end
- pollFirst() -> returns first value and deletes it
- pollLast() -> returns last value and deletes it
- peekFirst() -> returns first value
- peekLast() -> returns last value
- size() -> returns size of dequeue
Dictionary
https://en.wikipedia.org/wiki/Associative_array
The “dictionary”, also known as associative structure or array, is similar to the built-in dictionary in python.
from dictionary import*
assoc = Dictionary()
print(assoc.put("France", "Pari"))#None
print(assoc.put("Germany", "Berlin"))#None
print(assoc.put("Austria", "Vienna"))#None
print(assoc)
print(assoc.put("France", "Paris")) #Pari
print(assoc.remove("England")) #None
print(assoc.remove("Germany")) #Berlin
print(assoc)
print(assoc.containsKey("England"))#False
print(assoc.containsKey("France"))#True
print(assoc.containsValue("London"))#False
print(assoc.containsValue("Paris"))#True
print(assoc.size())#2
Available methods:
- put(key, value) -> adds the key-value pair or updates the value (returning old value)
- get(key) -> returns corresponding value for given key
- remove(key) -> removes the given key-value pair and returns it
- containsKey(key) -> returns true/false
- containsValue(value) -> returns true/false
- size() -> return number of key-value pairs
Linked List
https://en.wikipedia.org/wiki/Linked_list
from linkedlist import*
ll = LinkedList()
ll.addLast(1)
ll.addLast(2)
ll.addLast(3)
ll.addLast(4)
print(ll.getFirst()) #1
print(ll.getLast()) #4
for loop in range(ll.size()):
print(ll.get(loop)) #1 to 4
print(ll.pollFirst()) #1
print(ll)
Available methods:
- constructor(head: ListNode) -> Constructor with option to pass first Node, has to be a ListNode
- add(value, i) -> adds the given value to a ListNode inserted at position i
- addFirst(value) -> adds the given value to a ListNode in first position
- addLast(value) -> adds the given value to a ListNode in last position
- get(i) -> returns value at index i
- getFirst() -> returns value of “head” node
- getLast() -> returns value of last node
- pollFirst() -> returns value of head node and removes it
- pollLast() -> returns value of last node and removes it
- indexOf(value) -> returns index of given value or -1 if not found
- size() -> returns amount of Nodes in LinkedList
Binary Search Tree
https://en.wikipedia.org/wiki/Binary_search_tree
WIP: Better representation of the BST through the str() method
WIP: Add remove function for BST
- BST: Each Treenode has left and right child
- Key of left child always smaller then parent
- Key of right child always bigger then parent
from binarysearchtree import*
bst = BinarySearchTree()
bst.put(5,10)
bst.put(2,4)
bst.put(7,14)
bst.put(1,2)
bst.put(3,6)
print(bst.get(6)) #None
print(bst.get(2)) #4
print(bst.contains(10)) #False
print(bst)
Available methods:
- put(key, value) -> adds key-value pair to BST
- get(key) -> returns the associated value with key or None
- contains(key) -> returns True/False if key is in BST <=> get(key) != None
Usage of an internal “helper” class: Treenode (further documentation in source code)
Hashmap / Hashtable
https://en.wikipedia.org/wiki/Hash_table
The Hashmap is similar to the associative structure but doesn’t use a linear search to find elements inside of it, but computes the index with the object hash and in relation to the internal array size.
from hashmap import*
hm = Hashmap()
for loop in range(16):
hm.put(loop, loop*2)
print(hm)
for loop in range(16):
print(str(loop) + " => " + str(hm.get(loop)))
print()
print(hm.containsKey(10)) #True
print(hm.containsKey(18)) #False
hm.remove(10)
print(hm)
print(hm.containsKey(10)) #False
Available methods:
- index(value) -> returns index that value would have in hashmap (internal method)
- put(key, value) -> inserts or updates the value for the given key, and returns old value or None
- get(key) -> returns the value that is associated to the key or None
- containsKey(key) -> returns True/False if key is in the hashmap
- remove(key) -> removes the key/value pair from hashmap and returns True if key was removed (or False if not found)
Hashlist
https://en.wikipedia.org/wiki/Hash_list
A Hashlist is similar to a Hashmap but without the usage of a value associated to a key. Hashlistes can be used, for instance, to check in constant lookup time if an element exists.
from hashlist import*
hl = Hashlist()
hl.put("Python")
hl.put("C++")
hl.put("Java")
toCheck = ["Python","C++","C#","Java"]
for item in toCheck:
print(f"Element {item} in hashlist: {hl.contains(item)}") #True,True,False,True
print(hl.remove("Java"))#True
print(hl)
Available methods:
- index(value) -> returns index that value would have in hashlist
- put(value) -> adds value to hashlist
- contains(value) -> returns True/False if value in hashlist
- remove(value) -> removes value from hashlist and returns if something has been removed
Heap / Priority Queue
https://en.wikipedia.org/wiki/Priority_queue
A Heap or Priority Queue is a structure to save different “tasks”, each having a priority value (higher is more urgent) and an optional description. Priority Queues can be used to organize work and to deal with tasks that are more urgent. It can also be used to reduce the time complexity for algorithms (for instance Dijkstra Algorithm), because the operations on a Heap are in O(log n).
from heap import*
hp = Heap()
hp.put(1)
hp.put(6,"Prio 6")
hp.put(10,"Prio 10")
hp.put(5,"Prio 5")
hp.put(8,"Prio 8")
print(hp)
while hp.size() > 0:
print(hp.get()) #10 - 8 - 6 - 5 - 1
print(hp.get()) #None
Available methods:
- heapify(position) -> restores the heap condition for the index position and works up recursively
- heapifier() -> internal method to call all necessary “heapify() calls” to make sure that the heap condition is met again
- put(value) -> inserts value into the priority queue
- delete(positon) -> removes the element at position and restores heap condition with heapify
- get() -> returns item with highest priority (index 0) and deletes it