Skip to content
Open
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
150 changes: 83 additions & 67 deletions hashtable/hashtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,98 +22,114 @@ class HashTable:

def __init__(self, capacity):
# Your code here
# Your code here
# initialize the hash table with empty storage list entries
# size of the array = min 8
# will store our data in - set equal to None force python to get a list that has a fixed length
self.capacity = MIN_CAPACITY
self.bucket = [None] * self.capacity
self.count = 0

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

def get_num_slots(self):
"""
Return the length of the list you're using to hold the hash
table data. (Not the number of items stored in the hash table,
but the number of slots in the main list.)

One of the tests relies on this.

Implement this.
"""
# Your code here
return len(self.bucket)


def get_load_factor(self):
"""
Return the load factor for this hash table.

Implement this.
"""
# Your code here
return self.count / len(self.bucket)


def fnv1(self, key):
"""
FNV-1 Hash, 64-bit

Implement this, and/or DJB2.
"""

# Your code here

pass


def djb2(self, key):
"""
DJB2 hash, 32-bit

Implement this, and/or FNV-1.
"""
# Your code here
hash = 5381
# iterates characters in key,
for character in key:
# ord: numerical value of that character -->
hash = ((hash << 5) + hash) + ord(character)
return hash & 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.djb2(key) % self.capacity

def put(self, key, value):
"""
Store the value with the given key.

Hash collisions should be handled with Linked List Chaining.

Implement this.
"""
# Your code here

idx = self.hash_index(key)

node = HashTableEntry(key,value)

key = self.bucket[idx]

self.count += 1

# the key exist
if key:
# overwrite with the node
self.bucket[idx] = node
self.bucket[idx].next = key
# if self.capacity[index] exist,
# use LL to set next to the repeated key and value
else:
self.bucket[idx] = node
# print('adding node', node.next)
print(self.bucket)
return self.bucket[idx]

def delete(self, key):
"""
Remove the value stored with the given key.

Print a warning if the key is not found.

Implement this.
"""
# Your code here


self.count -= 1
self.put(key, None)

def get(self, key):
"""
Retrieve the value stored with the given key.

Returns None if the key is not found.

Implement this.
"""
# Your code here
idx = self.hash_index(key)

arr = self.bucket[idx]

while arr:
if arr.key == key:
return arr.value
arr = arr.next



def resize(self, new_capacity):
"""
Changes the capacity of the hash table and
rehashes all key/value pairs.

Implement this.
"""
# Your code here

if self.get_load_factor() < 0.2:
self.capacity = new_capacity // 2
prev_bucket = self.bucket # [None, None, None, None, None, None, None, None].
self.bucket = [None] * self.capacity # [None, None, None, None]

for node in prev_bucket: # Traverse thru all the nodes.

if node != None:
self.put( node.key, node.value )
else:
continue


if self.get_load_factor() > 0.7:
self.capacity = new_capacity * 2
prev_bucket = self.bucket # [None, None, None, None, None, None, None, None].
self.bucket = [None] * self.capacity

for node in prev_bucket: # Traverse thru all the nodes.

if node != None:
self.put( node.key, node.value )
else:
continue










Expand Down