Question: Write the functions in python please and include explanations and screenshots for each class Question 1a) Define a class named HashTable to represent a hash
Write the functions in python please and include explanations and screenshots for each class
Question 1a)
Define a class named HashTable to represent a hash table. The HashTable class contains the following methods:
- A private data field named __size that defines the size of a hash table.
- A private data field named __slots that defines a list containing a number of slots of a hash table. The number of slots is the size of a hash table. You can assume that the data stored in the hash table are integers. The underlying data structure of a hash table is a python list.
- A constructor/initializer which takes an integer as a parameter and creates a hash table with the size specified by the integer parameter. The initializer should initialize __slotsto a list of None objects. For example, if the size of a hash table is 5, then the __slots is [None, None, None, None, None]. The None value will be used to represent empty positions in a hash table. The default size is 7.
- The __str__(self) method which returns a string representation of the object formatted as in the examples below.
- The get_hash_code(self, key) method which takes an integer as a parameter and returns a hash code value based on the parameter key. The method should use this formula to calculate the value: key % (size of hash table).
| Test | Result |
my_hash_table = HashTable() print(my_hash_table) print(type(my_hash_table)) print(my_hash_table.get_hash_code(12)) | [None, None, None, None, None, None, None] |
my_hash_table = HashTable(3) print(my_hash_table) print(my_hash_table.get_hash_code(14)) | [None, None, None] 2 |
Question 1b)
Continuing on with your HashTable class implementation, extend the HashTable class by adding the following methods:
- The put(self, key) method which takes an integer as a parameter and inserts the parameter key into a hash table. For simplicity, we assume that the key and value are the same in this question and you may also assume that no collisions occur and there is enough space for the value.
- The __len__(self) method which returns the number of elements present in a hash table.
| Test | Result |
my_hash_table = HashTable(13) my_hash_table.put(26) my_hash_table.put(54) my_hash_table.put(94) my_hash_table.put(17) print(my_hash_table) print("The hash table contains {} items.".format(len(my_hash_table))) | [26, None, 54, 94, 17, None, None, None, None, None, None, None, None] The hash table contains 4 items. |
Question 1c)
Continuing on with your HashTable class implementation,
- The get_new_hash_code_linear_probing(self, index) method which takes an integer as a parameter and uses the linear probing technique to determine where the key should be placed in the hash table when a collision occurs.
- Modify the put(self, key) method. The method should call the get_new_hash_code_linear_probing() method to calculate the next available index position when a collision occurs.
Note: You may assume there will be space in the hash table for the key.
| Test | Result |
my_hash_table = HashTable(13) my_hash_table.put(13) my_hash_table.put(26) my_hash_table.put(14) my_hash_table.put(15) my_hash_table.put(16) my_hash_table.put(17) print(my_hash_table) | [13, 26, 14, 15, 16, 17, None, None, None, None, None, None, None] |
my_hash_table = HashTable(13) my_hash_table.put(12) my_hash_table.put(24) my_hash_table.put(36) my_hash_table.put(48) my_hash_table.put(31) my_hash_table.put(77) my_hash_table.put(43) |
Question 1d)
Starting with your solution to the HashTable class definition, define a class named QuadraticHashTable. The QuadraticHashtable class contains the same methods defined in the HashTable class except the put() method.
- Add a method named get_new_hash_code_quadratic_probing(self, index, step) which takes two integers as parameters and uses the quadratic probing technique to determine where the key should be placed in the hash table when a collision occurs.
- Modify the put(self, key) method. The method should call the get_new_hash_code_quadratic_probing() method to calculate the next index position when a collision occurs. The method should raise an IndexError with the message "ERROR: The hash table is full." if the hash table is full when the put() method is called.
For example, if the current hash table is [None, 1, 8, None, None, 15, None] and we would like to insert "22" into the hash table, you will get:
index = 22 % 7 = 1 (collision) new_index = (1 + 1 * 1) % 7 = 2 (collision) new_index = (1 + 2 * 2) % 7 = 5 (collision) new_index = (1 + 3 * 3) % 7 = 3
Therefore, the next position is 3.
| Test | Result |
my_hash_table=QuadraticHashTable() my_hash_table.put(1) print(my_hash_table) my_hash_table.put(8) print(my_hash_table) my_hash_table.put(15) print(my_hash_table) my_hash_table.put(22) print(my_hash_table) | [None, 1, None, None, None, None, None] [None, 1, 8, None, None, None, None] [None, 1, 8, None, None, 15, None] [None, 1, 8, 22, None, 15, None] |
Question 1e)
Starting with your solution to the HashTable class definition, define a class named DoubleHashTable. The DoubleHashtable contains the same methods defined in the HashTable class except the implentation of the __init__() and put() methods.
- Modify the __init__(self, size, second_hash_value) method. The initializer takes two integers as parameters. The first parameter defines the size of the hash table and the second parameter defines the prime number to be used in the secondary hash function. The default size value is 7, and the default value for the secondary hash function is 5.
- Add a method called get_new_hash_code_double_hashing(self, key) method. This method takes an integer as a parameter and uses the double hashing probing technique to determine where the key should be placed in the hash table when a collision occurs. The secondary hash function is: second_hash_value - (key % second_hash_value) where second_hash_value is a prime number that was assigned in the __init__() function.
- Modify the put(self, key) method. The method should call the get_new_hash_code_double_hashing() method to calculate the new index position to try when a collision occurs. Use the following formula to calculate the next index position to try: next_index = (index + step * step_value) % size where step represents the number of collisions and step_value is the value calculated from the second hash function.
For example, consider the first example given below, my_hash_table = DoubleHashTable(), the size of the hash table is 7, the value of second_hash_value is 5 and the current hash table is: [None, 1, None, 8, None, None, 5] and we would like to insert "22" into the hash table using double hashing, you will get:
index = 22 % 7 = 1 (collision) step_value = 5 - (22 % 5) = 3 next_index = (1 + 1 * 3) % 7 = 4
Therefore, the new insertion position is 4.
Another example: if the current hash table is [None, 1, None, 8, 22, None, 5] and we would like to insert "41":
index = 41 % 7 = 6 (collision) step_value = 5 - (41 % 5) = 4 next_index = (6 + 1 * 4) % 7 = 3 (collision) next_index = (6 + 2 * 4) % 7 = 0
| Test | Result |
my_hash_table=DoubleHashTable() my_hash_table.put(1) print(my_hash_table) my_hash_table.put(8) print(my_hash_table) my_hash_table.put(15) print(my_hash_table) my_hash_table.put(22) print(my_hash_table) my_hash_table.put(41) print(my_hash_table) | [None, 1, None, None, None, None, None] [None, 1, None, 8, None, None, None] [None, 1, None, 8, None, None, 15] [None, 1, None, 8, 22, None, 15] [41, 1, None, 8, 22, None, 15] |
my_hash_table=DoubleHashTable() my_hash_table.put(26) my_hash_table.put(54) my_hash_table.put(94) my_hash_table.put(15) my_hash_table.put(28) print(my_hash_table) | [28, 15, None, 94, None, 26, 54] |
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
