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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__pycache__
.vscode
.idea
96 changes: 88 additions & 8 deletions hashtable/hashtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,55 @@ class HashTableEntry:
"""
Linked List hash table key/value pair
"""

def __init__(self, key, value):
self.key = key
self.value = value
self.next = None

def __repr__(self):
return f"The key is: {self.key}, and the value is: {self.value}"


class LinkedList:

def __init__(self):
self.head = None

def find(self, key):
current_node = self.head
while current_node is not None:
if current_node.key == key:
return current_node
current_node = current_node.next
return None

def insert_at_head(self, node):
# Link the node to the current HEAD
node.next = self.head
# Set head pointer to new node
self.head = node

def delete(self, key):
# Handle the case where the node to delete is the HEAD
if key == self.head.key:
self.head = self.head.next
return self.head

prev = None
curr = self.head

while curr is not None:
if curr.key == key:
prev.next = curr.next
return curr

prev = curr
curr = curr.next

# Hash table can't have fewer than this many slots


# Hash table can't have fewer than this many slots
MIN_CAPACITY = 8


Expand All @@ -22,7 +64,9 @@ class HashTable:

def __init__(self, capacity):
# Your code here

self.capacity = capacity
self.table = [None] * capacity
self.count = 0

def get_num_slots(self):
"""
Expand All @@ -35,7 +79,7 @@ def get_num_slots(self):
Implement this.
"""
# Your code here

return len(self.table)

def get_load_factor(self):
"""
Expand All @@ -44,7 +88,7 @@ def get_load_factor(self):
Implement this.
"""
# Your code here

return self.count / len(self.table)

def fnv1(self, key):
"""
Expand All @@ -54,7 +98,15 @@ def fnv1(self, key):
"""

# Your code here
fnv_prime = 16777619
offset_basis = 2166136261

# FNV-1a Hash Function
hashed = offset_basis + key
for char in self.capacity:
hashed = hashed * fnv_prime
hashed = hashed ^ ord(char)
return hash

def djb2(self, key):
"""
Expand All @@ -63,14 +115,19 @@ def djb2(self, key):
Implement this, and/or FNV-1.
"""
# Your code here
str_key = str(key).encode()
hash_value = 5381
for s in str_key:
hash_value = ((hash_value << 5) + hash_value) + s

return hash_value & 0xffffffff

def hash_index(self, key):
"""
Take an arbitrary key and return a valid integer index
between within the storage capacity of the hash table.
"""
#return self.fnv1(key) % self.capacity
# return self.fnv1(key) % self.capacity
return self.djb2(key) % self.capacity

def put(self, key, value):
Expand All @@ -82,7 +139,14 @@ def put(self, key, value):
Implement this.
"""
# Your code here
hashed_index = self.hash_index(key)
if self.table[hashed_index] is not None:
pass
# TODO working on getting linked list to work

else:
self.count = self.count + 1
self.table[hashed_index] = (HashTableEntry(key, value))

def delete(self, key):
"""
Expand All @@ -93,7 +157,9 @@ def delete(self, key):
Implement this.
"""
# Your code here

hashed_key = self.djb2(key)
hashed_index = self.hash_index(hashed_key)
self.table[hashed_index] = None

def get(self, key):
"""
Expand All @@ -104,7 +170,9 @@ def get(self, key):
Implement this.
"""
# Your code here

hashed_key = self.djb2(key)
hashed_index = self.hash_index(hashed_key)
return self.table[hashed_index]

def resize(self, new_capacity):
"""
Expand All @@ -114,7 +182,19 @@ def resize(self, new_capacity):
Implement this.
"""
# Your code here

if self.count == 0:
self.capacity = new_capacity
self.table = [None] * self.capacity

new_table = [None] * new_capacity
for item in enumerate(self.table):
if item is None:
pass
hashed_key = self.djb2(item)
hashed_index = self.hash_index(hashed_key)
new_table.insert(hashed_index, item)

self.table = new_table


if __name__ == "__main__":
Expand Down
2 changes: 2 additions & 0 deletions hashtable/test_hashtable_no_collisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import unittest
from hashtable import HashTable


class TestHashTable(unittest.TestCase):

def test_hash_table_insertion_and_retrieval(self):
Expand Down Expand Up @@ -67,5 +68,6 @@ def test_hash_table_removes_correctly(self):
return_value = ht.get("key-2")
self.assertTrue(return_value is None)


if __name__ == '__main__':
unittest.main()