implement hashtable class

This commit is contained in:
mljoshi 2024-06-16 21:12:43 -07:00
parent 851ce00dbe
commit d0d6dbb5c7

View File

@ -4,39 +4,168 @@
#include <stdexcept>
#include "HashNode.h"
template<typename T>
class HashTable {
template <typename T>
class HashTable
{
private:
HashNode<T> *hashAry;
int hashSize;
int count;
HashNode<T> *hashAry;
public:
HashTable() : hashSize(97), count(0) {
HashTable()
{
count = 0;
hashSize = 97;
hashAry = new HashNode<T>[hashSize];
};
}
HashTable(int n)
{
count = 0;
hashSize = n;
hashAry = new HashNode<T>[hashSize];
}
~HashTable() { delete[] hashAry; }
~HashTable() { delete[] hashAry; };
int getCount() const { return count; }
int getHashSize() const { return hashSize; }
double getLoadFactor() const { return 100.0 * count / hashSize; }
bool isEmpty() const { return count == 0; }
bool isFull() const { return count == hashSize; }
[[nodiscard]] int getCount() const { return count; };
int getTotalCollisions() const;
int getMaxCollisions() const;
[[nodiscard]] int getHashSize() const { return hashSize; };
bool isEmpty() const { return count == 0; };
bool isFull() const { return count == hashSize; };
double getLoadFactor() const { throw std::logic_error("Not implemented: HashTable.getLoadFactor()"); };
bool insert(const T &item, int h(const T&, int)) { throw std::logic_error("Not implemented: HashTable.insert()"); };
bool remove(const T &item, int h(const T&, int)) { throw std::logic_error("Not implemented: HashTable.remove()"); };
bool search(T& itemOut, const T &item, int h(const T&, int)) { throw std::logic_error("Not implemented: HashTable.search()"); };
int getTotalCollisions() const { throw std::logic_error("Not implemented: HashTable.getTotalCollisions()"); };
int getMaxCollisions() const { throw std::logic_error("Not implemented: HashTable.getMaxCollisions()"); };
bool insert(const T &itemIn, int h(const T &key, int size));
bool remove(T &itemOut, const T &key, int h(const T &key, int size));
int search(T &itemOut, const T &key, int h(const T &key, int size)) const;
};
#endif //INC_08_TEAM_PROJECT_HASHTABLE_H
/*~*~*~*
Get total number of collisions throughout hash table
*~**/
template <typename T>
int HashTable<T>::getTotalCollisions() const
{
int total = 0;
for (int i = 0; i < hashSize; i++)
{
if (hashAry[i].getOccupied() == 1)
{
total += hashAry[i].getNumCollisions();
}
}
return total;
}
/*~*~*~*
Get longest collision length in hash table
*~**/
template <typename T>
int HashTable<T>::getMaxCollisions() const
{
int high = 0;
for (int i = 0; i < hashSize; i++)
{
if (hashAry[i].getOccupied() == 1 && hashAry[i].getNumCollisions() > high)
{
high = hashAry[i].getNumCollisions();
}
}
return high;
}
/*~*~*~*
Insert an item into the hash table
It does not reject duplicates
*~**/
template <typename T>
bool HashTable<T>::insert(const T &itemIn, int h(const T &key, int size))
{
if (count == hashSize)
return false;
int ind = h(itemIn, hashSize);
for (int i = 0; i < hashSize; i++)
{
if (hashAry[(ind + i) % hashSize].getOccupied() != 1)
{
hashAry[(ind + i) % hashSize].setOccupied(1);
hashAry[(ind + i) % hashSize].setItem(itemIn);
hashAry[(ind + i) % hashSize].setNumCollisions(i);
count++;
break;
}
}
return true;
}
/*~*~*~*
Removes the item with the matching key from the hash table
if found:
- copies data in the hash node to itemOut
- replaces data in the hash node with an empty record (occupied = -1: deleted!)
- returns true
if not found:
- returns false
*~**/
template <typename T>
bool HashTable<T>::remove(T &itemOut, const T &key, int h(const T &key, int size))
{
int ind = h(key, hashSize);
for (int i = 0; i < hashSize; i++)
{
if (hashAry[(ind + i) % hashSize].getOccupied() == 1)
{
if (hashAry[(ind + i) % hashSize].getItem() == key)
{
itemOut = hashAry[(ind + i) % hashSize].getItem();
hashAry[(ind + i) % hashSize].setOccupied(-1);
// Do not access a node with occupied of -1
count--;
return true;
}
}
else if (hashAry[(ind + 1) % hashSize].getOccupied() == 0)
{
// If using linear probing and we come across a spot that has been empty since start, the item is not in the table
break;
}
}
return false;
}
/*~*~*~*
hash search - linear probe
if found:
- copy data to itemOut
- returns the number of collisions for this key
if not found, returns -1
*~**/
template <typename T>
int HashTable<T>::search(T &itemOut, const T &key, int h(const T &key, int size)) const
{
int ind = h(key, hashSize);
for (int i = 0; i < hashSize; i++)
{
if (hashAry[(ind + i) % hashSize].getOccupied() == 1)
{
if (hashAry[(ind + i) % hashSize].getItem() == key)
{
itemOut = hashAry[(ind + i) % hashSize].getItem();
return hashAry[(ind + i) % hashSize].getNumCollisions();
}
}
else if (hashAry[(ind + 1) % hashSize].getOccupied() == 0)
{
// If using linear probing and we come across a spot that has been empty since start, the item is not in the table
break;
}
}
return -1;
}
#endif // INC_08_TEAM_PROJECT_HASHTABLE_H