I'm currently doing hashing in my class. I need to create a double hashing function which takes a list and uses double hashing and returns a new list.
I understand how a list uses double hashing but I have trouble writing down the code for it.
hashkey = key % len(list)
steps = q - (key % q)
new_hashkey = steps + hashkey
#q = double_hash_value
This is the double hashing function that I have learned in class. I just have trouble implementing it in the code.
This is my attempt so far:
def double_hashing(keys, hashtable_size, double_hash_value):
hashtable_list = [None] * hashtable_size
for i in range(len(keys)):
hashkey = keys[i] % hashtable_size
if hashtable_list[hashkey] is None:
hashtable_list[hashkey] = keys[i]
else:
new_hashkey = hashkey
while hashtable_list[new_hashkey] is not None:
steps = double_hash_value - (keys[i] % double_hash_value)
new_hashkey = hashkey + steps
hashtable_list[new_hashkey] = keys[i]
return hashtable_list
values = [26, 54, 94, 17, 31, 77, 44, 51]
double = double_hashing(values, 13, 5)
print('Double =', double)
I'm fairly sure this is close to being right but I'm just making a stupid mistake or something. I understand how double hashing works but this code above does not work.
The output for this should be:
[26, None, 54, 94, 17, 31, 44, 51, None, None, None, None, 77]
but my output is:
[26, None, 54, 94, 17, 31, 44, None, None, None, None, None, 77]
The value 51 in index position is not being added.
Any help is appreciated. Thank you.
Your function has two problems as far as I can tell:
Problem 1 is that in your while
loop, you were using hashkey
to update the value of new_hashkey
which meant that if your function failed to find an appropriate index for a given value in the first iteration of the while loop, it would never find it since the value of new_hashkey
would never change. Also by simply adding the steps
to new_hashkey
you run the risk of having a new_hashkey
that is greater than your hashtable_size
which will eventually throw an IndexError
. You can fix that by taking that value modulo the hashtable_size
.
Secondly, your function was returning too early. In your example, it was returning after it encountered 44
(i.e. the first time it entered the else
block), which was why you weren't adding 51
to your output list. Your return statement should really be after the for loop is finished so that you are sure to add all the values in the keys
list to your output list.
See the updated code below (changed lines are commented):
def double_hashing(keys, hashtable_size, double_hash_value):
hashtable_list = [None] * hashtable_size
for i in range(len(keys)):
hashkey = keys[i] % hashtable_size
if hashtable_list[hashkey] is None:
hashtable_list[hashkey] = keys[i]
else:
new_hashkey = hashkey
while hashtable_list[new_hashkey] is not None:
steps = double_hash_value - (keys[i] % double_hash_value)
new_hashkey = (new_hashkey + steps) % hashtable_size ## problem 1 is here
hashtable_list[new_hashkey] = keys[i]
return hashtable_list ## problem 2 is here
values = [26, 54, 94, 17, 31, 77, 44, 51]
print( double_hashing(values, 13, 5) )
[26, None, 54, 94, 17, 31, 44, 51, None, None, None, None, 77]