|
| 1 | +#!/usr/bin/env python3 |
| 2 | +from number_theory.prime_numbers import next_prime |
| 3 | + |
| 4 | + |
| 5 | +class HashTable: |
| 6 | + """ |
| 7 | + Basic Hash Table example with open addressing and linear probing |
| 8 | + """ |
| 9 | + |
| 10 | + def __init__(self, size_table, charge_factor=None, lim_charge=None): |
| 11 | + self.size_table = size_table |
| 12 | + self.values = [None] * self.size_table |
| 13 | + self.lim_charge = 0.75 if lim_charge is None else lim_charge |
| 14 | + self.charge_factor = 1 if charge_factor is None else charge_factor |
| 15 | + self.__aux_list = [] |
| 16 | + self._keys = {} |
| 17 | + |
| 18 | + def keys(self): |
| 19 | + return self._keys |
| 20 | + |
| 21 | + def balanced_factor(self): |
| 22 | + return sum([1 for slot in self.values |
| 23 | + if slot is not None]) / (self.size_table * self.charge_factor) |
| 24 | + |
| 25 | + def hash_function(self, key): |
| 26 | + return key % self.size_table |
| 27 | + |
| 28 | + def _step_by_step(self, step_ord): |
| 29 | + |
| 30 | + print("step {0}".format(step_ord)) |
| 31 | + print([i for i in range(len(self.values))]) |
| 32 | + print(self.values) |
| 33 | + |
| 34 | + def bulk_insert(self, values): |
| 35 | + i = 1 |
| 36 | + self.__aux_list = values |
| 37 | + for value in values: |
| 38 | + self.insert_data(value) |
| 39 | + self._step_by_step(i) |
| 40 | + i += 1 |
| 41 | + |
| 42 | + def _set_value(self, key, data): |
| 43 | + self.values[key] = data |
| 44 | + self._keys[key] = data |
| 45 | + |
| 46 | + def _colision_resolution(self, key, data=None): |
| 47 | + new_key = self.hash_function(key + 1) |
| 48 | + |
| 49 | + while self.values[new_key] is not None \ |
| 50 | + and self.values[new_key] != key: |
| 51 | + |
| 52 | + if self.values.count(None) > 0: |
| 53 | + new_key = self.hash_function(new_key + 1) |
| 54 | + else: |
| 55 | + new_key = None |
| 56 | + break |
| 57 | + |
| 58 | + return new_key |
| 59 | + |
| 60 | + def rehashing(self): |
| 61 | + survivor_values = [value for value in self.values if value is not None] |
| 62 | + self.size_table = next_prime(self.size_table, factor=2) |
| 63 | + self._keys.clear() |
| 64 | + self.values = [None] * self.size_table #hell's pointers D: don't DRY ;/ |
| 65 | + map(self.insert_data, survivor_values) |
| 66 | + |
| 67 | + def insert_data(self, data): |
| 68 | + key = self.hash_function(data) |
| 69 | + |
| 70 | + if self.values[key] is None: |
| 71 | + self._set_value(key, data) |
| 72 | + |
| 73 | + elif self.values[key] == data: |
| 74 | + pass |
| 75 | + |
| 76 | + else: |
| 77 | + colision_resolution = self._colision_resolution(key, data) |
| 78 | + if colision_resolution is not None: |
| 79 | + self._set_value(colision_resolution, data) |
| 80 | + else: |
| 81 | + self.rehashing() |
| 82 | + self.insert_data(data) |
| 83 | + |
| 84 | + |
0 commit comments