Skip to content

Commit

Permalink
hash functions added
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriel committed Mar 20, 2018
1 parent aa8485b commit 1fa23f5
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 0 deletions.
6 changes: 6 additions & 0 deletions data_structures/hashing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from .hash_table import HashTable

class QuadraticProbing(HashTable):

def __init__(self):
super(self.__class__, self).__init__()
33 changes: 33 additions & 0 deletions data_structures/hashing/double_hash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3

from .hash_table import HashTable
from number_theory.prime_numbers import next_prime, check_prime


class DoubleHash(HashTable):
"""
Hash Table example with open addressing and Double Hash
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def __hash_function_2(self, value, data):

next_prime_gt = next_prime(value % self.size_table) \
if not check_prime(value % self.size_table) else value % self.size_table #gt = bigger than
return next_prime_gt - (data % next_prime_gt)

def __hash_double_function(self, key, data, increment):
return (increment * self.__hash_function_2(key, data)) % self.size_table

def _colision_resolution(self, key, data=None):
i = 1
new_key = self.hash_function(data)

while self.values[new_key] is not None and self.values[new_key] != key:
new_key = self.__hash_double_function(key, data, i) if \
self.balanced_factor() >= self.lim_charge else None
if new_key is None: break
else: i += 1

return new_key
84 changes: 84 additions & 0 deletions data_structures/hashing/hash_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python3
from number_theory.prime_numbers import next_prime


class HashTable:
"""
Basic Hash Table example with open addressing and linear probing
"""

def __init__(self, size_table, charge_factor=None, lim_charge=None):
self.size_table = size_table
self.values = [None] * self.size_table
self.lim_charge = 0.75 if lim_charge is None else lim_charge
self.charge_factor = 1 if charge_factor is None else charge_factor
self.__aux_list = []
self._keys = {}

def keys(self):
return self._keys

def balanced_factor(self):
return sum([1 for slot in self.values
if slot is not None]) / (self.size_table * self.charge_factor)

def hash_function(self, key):
return key % self.size_table

def _step_by_step(self, step_ord):

print("step {0}".format(step_ord))
print([i for i in range(len(self.values))])
print(self.values)

def bulk_insert(self, values):
i = 1
self.__aux_list = values
for value in values:
self.insert_data(value)
self._step_by_step(i)
i += 1

def _set_value(self, key, data):
self.values[key] = data
self._keys[key] = data

def _colision_resolution(self, key, data=None):
new_key = self.hash_function(key + 1)

while self.values[new_key] is not None \
and self.values[new_key] != key:

if self.values.count(None) > 0:
new_key = self.hash_function(new_key + 1)
else:
new_key = None
break

return new_key

def rehashing(self):
survivor_values = [value for value in self.values if value is not None]
self.size_table = next_prime(self.size_table, factor=2)
self._keys.clear()
self.values = [None] * self.size_table #hell's pointers D: don't DRY ;/
map(self.insert_data, survivor_values)

def insert_data(self, data):
key = self.hash_function(data)

if self.values[key] is None:
self._set_value(key, data)

elif self.values[key] == data:
pass

else:
colision_resolution = self._colision_resolution(key, data)
if colision_resolution is not None:
self._set_value(colision_resolution, data)
else:
self.rehashing()
self.insert_data(data)


24 changes: 24 additions & 0 deletions data_structures/hashing/hash_table_with_linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from .hash_table import HashTable
from collections import deque


class HashTableWithLinkedList(HashTable):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def _set_value(self, key, data):
self.values[key] = deque([]) if self.values[key] is None else self.values[key]
self.values[key].appendleft(data)
self._keys[key] = self.values[key]

def balanced_factor(self):
return sum([self.charge_factor - len(slot) for slot in self.values])\
/ self.size_table * self.charge_factor

def _colision_resolution(self, key, data=None):
if not (len(self.values[key]) == self.charge_factor
and self.values.count(None) == 0):
return key
return super()._colision_resolution(key, data)


Empty file.
29 changes: 29 additions & 0 deletions data_structures/hashing/number_theory/prime_numbers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""
module to operations with prime numbers
"""


def check_prime(number):
"""
it's not the best solution
"""
special_non_primes = [0,1,2]
if number in special_non_primes[:2]:
return 2
elif number == special_non_primes[-1]:
return 3

return all([number % i for i in range(2, number)])


def next_prime(value, factor=1, **kwargs):
value = factor * value
first_value_val = value

while not check_prime(value):
value += 1 if not ("desc" in kwargs.keys() and kwargs["desc"] is True) else -1

if value == first_value_val:
return next_prime(value + 1, **kwargs)
return value
26 changes: 26 additions & 0 deletions data_structures/hashing/quadratic_probing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3

from .hash_table import HashTable


class QuadraticProbing(HashTable):
"""
Basic Hash Table example with open addressing using Quadratic Probing
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def _colision_resolution(self, key, data=None):
i = 1
new_key = self.hash_function(key + i*i)

while self.values[new_key] is not None \
and self.values[new_key] != key:
i += 1
new_key = self.hash_function(key + i*i) if not \
self.balanced_factor() >= self.lim_charge else None

if new_key is None:
break

return new_key

0 comments on commit 1fa23f5

Please sign in to comment.