Open Addressing
In this part, you'll implement open addressing for your HashSet<T> class template. Open addressing is a collision-resolution technique in hash tables where, if a collision occurs, the algorithm searches for the next available slot in the hash table.
Although this part might be the most challenging of the optional parts, it is also a great opportunity to deepen your understanding of hash tables and collision-resolution strategies. And it actually isn't too bad, especially if you haven't done the other optional parts.
The biggest difference between open addressing and separate chaining (which you used in the main part of the assignment) is that, with open addressing, all elements are stored directly in the array that represents the hash table. There are no linked lists or other secondary data structures. When a collision occurs, the algorithm probes the array to find the next available slot.
Your Task
-
Copy your code from
hashset.hppandhashset-private.hppinto new files namedoahashset.hppandoahashset-private.hpp, respectively. -
Change all the names in the new files, including
HashSet<T>toOAHashSet<T>HASHSET_HPP_INCLUDEDtoOAHASHSET_HPP_INCLUDED#include "hashset-private.hpp"to#include "oahashset-private.hpp"
-
Remove
std::forward_list<T>as the element type of the buckets array; instead you'll be storing aT*array (i.e., an array of pointers toTobjects). For clarity, it may be helpful to add a type alias within yourOAHashSet<T>class template similar tousing BucketType = T*; -
Update your constructor to initialize the buckets array with
nullptrvalues, indicating that all slots are initially empty. -
Likewise, ensure that
- Your resize logic correctly allocates a new array of
T*s and initializes all slots tonullptr; and - Your destructor properly deletes any dynamically allocated
Tobjects and the buckets array itself.
- Your resize logic correctly allocates a new array of
-
Implement the
insertmethod using linear probing to find the next available slot when a collision occurs. When inserting an element, if the computed bucket index is already occupied (i.e., notnullptr), you should probe linearly (i.e., check the next index, wrapping around to the beginning of the array if necessary) until you find an empty slot. -
Implement the
existsmethod to check for the presence of an element in the hash table. This function will also require the use of linear probing to search through the array until either the element is found or an empty slot is encountered (indicating that the element is not present). -
Update your rehashing logic to correctly transfer elements from the old buckets array to the new one, using the new hash function and linear probing as needed.
When You're Done
Don't forget to add some details about what you did to Fun.md. The sample solution includes an open-addressing implementation, so you can leave your tests in hashset-test.cpp enabled if you'd like rather than commenting them out.
(When logged in, completion status appears here.)