diff --git a/data_structures/hashing/hash_table.py b/data_structures/hashing/hash_table.py index 5bf431328da4..7fe57068f6a3 100644 --- a/data_structures/hashing/hash_table.py +++ b/data_structures/hashing/hash_table.py @@ -52,6 +52,30 @@ def balanced_factor(self): ) def hash_function(self, key): + """ + Generates hash for the given key value + + Examples: + + Creating HashTable with size 5 + >>> ht = HashTable(5) + >>> ht.hash_function(10) + 0 + >>> ht.hash_function(20) + 0 + >>> ht.hash_function(4) + 4 + >>> ht.hash_function(18) + 3 + >>> ht.hash_function(-18) + 2 + >>> ht.hash_function(18.5) + 3.5 + >>> ht.hash_function(0) + 0 + >>> ht.hash_function(-0) + 0 + """ return key % self.size_table def _step_by_step(self, step_ord): @@ -105,10 +129,99 @@ def bulk_insert(self, values): i += 1 def _set_value(self, key, data): + """ + _set_value functions allows to update value at a particular hash + + Examples: + 1. _set_value in HashTable of size 5 + >>> ht = HashTable(5) + >>> ht.insert_data(10) + >>> ht.insert_data(20) + >>> ht.insert_data(30) + >>> ht._set_value(0,15) + >>> ht.keys() + {0: 15, 1: 20, 2: 30} + + 2. _set_value in HashTable of size 2 + >>> ht = HashTable(2) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht._set_value(3,15) + >>> ht.keys() + {3: 15, 2: 17, 4: 99} + + 3. _set_value in HashTable when hash is not present + >>> ht = HashTable(2) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht._set_value(0,15) + >>> ht.keys() + {3: 18, 2: 17, 4: 99, 0: 15} + + 4. _set_value in HashTable when multiple hash are not present + >>> ht = HashTable(2) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht._set_value(0,15) + >>> ht._set_value(1,20) + >>> ht.keys() + {3: 18, 2: 17, 4: 99, 0: 15, 1: 20} + """ self.values[key] = data self._keys[key] = data def _collision_resolution(self, key, data=None): + """ + This method is a type of open addressing which is used for handling collision. + + In this implementation the concept of linear probing has been used. + + The hash table is searched sequentially from the original location of the + hash, if the new hash/location we get is already occupied we check for the next + hash/location. + + references: + - https://en.wikipedia.org/wiki/Linear_probing + + Examples: + 1. The collision will be with keys 18 & 99, so new hash will be created for 99 + >>> ht = HashTable(3) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht.keys() + {2: 17, 0: 18, 1: 99} + + 2. The collision will be with keys 17 & 101, so new hash + will be created for 101 + >>> ht = HashTable(4) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht.insert_data(101) + >>> ht.keys() + {1: 17, 2: 18, 3: 99, 0: 101} + + 2. The collision will be with all keys, so new hash will be created for all + >>> ht = HashTable(1) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99) + >>> ht.keys() + {2: 17, 3: 18, 4: 99} + + 3. Trying to insert float key in hash + >>> ht = HashTable(1) + >>> ht.insert_data(17) + >>> ht.insert_data(18) + >>> ht.insert_data(99.99) + Traceback (most recent call last): + ... + TypeError: list indices must be integers or slices, not float + """ new_key = self.hash_function(key + 1) while self.values[new_key] is not None and self.values[new_key] != key: