forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
gabriel
committed
Mar 20, 2018
1 parent
aa8485b
commit 1fa23f5
Showing
7 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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__() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |