diff --git a/06-hash-tables/HashTable.cpp b/06-hash-tables/HashTable.cpp index fb22846..5aa0fc5 100644 --- a/06-hash-tables/HashTable.cpp +++ b/06-hash-tables/HashTable.cpp @@ -27,7 +27,7 @@ bool HashTable::insert(const Student &itemIn) { return false; int pos = _hash(itemIn.getName()); int collisions = 0; - while (hashAry[pos].getOccupied()) { + while (hashAry[pos].getOccupied() == 1) { ++pos; ++collisions; pos = pos % hashSize; @@ -43,7 +43,18 @@ bool HashTable::insert(const Student &itemIn) { /*~*~*~* hash delete - linear probe *~**/ -bool HashTable::remove(Student &itemOut) { +bool HashTable::remove(Student &itemOut, string key) { + int pos = _hash(key); + for (int collisions = 0; collisions < count; collisions++) { + if (hashAry[pos].getOccupied() == 1 && hashAry[pos].getItem().getName() == key) { + itemOut = hashAry[pos].getItem(); + // -1 means freed + hashAry[pos].setOccupied(-1); + count--; + return true; + } + pos = (pos + 1) % hashSize; + } return false; } @@ -56,16 +67,15 @@ bool HashTable::remove(Student &itemOut) { - returns true if not found, returns false *~**/ -bool HashTable::search(Student &itemOut, int &noCol, string key) { +int HashTable::search(Student &itemOut, string key) const { int pos = _hash(key); for (int collisions = 0; collisions < count; collisions++) { - if (!hashAry[pos].getOccupied()) return false; - if (hashAry[pos].getItem().getName() == key) { + if (hashAry[pos].getOccupied() == 0) return -1; + if (hashAry[pos].getOccupied() == 1 && hashAry[pos].getItem().getName() == key) { itemOut = hashAry[pos].getItem(); - noCol = hashAry[pos].getNoCollisions(); - return true; + return hashAry[pos].getNoCollisions(); } pos = (pos + 1) % hashSize; } - return false; + return -1; } diff --git a/06-hash-tables/HashTable.h b/06-hash-tables/HashTable.h index 35bf1a4..8ae678d 100644 --- a/06-hash-tables/HashTable.h +++ b/06-hash-tables/HashTable.h @@ -40,9 +40,9 @@ public: bool insert(const Student &itemIn); - bool remove(Student &itemOut); + bool remove(Student &itemOut, string key); - bool search(Student &itemOut, int &noCol, string key); + int search(Student &itemOut, string key) const; private: int _hash(string key) const; diff --git a/06-hash-tables/main.cpp b/06-hash-tables/main.cpp index b4eddfb..4ee4925 100644 --- a/06-hash-tables/main.cpp +++ b/06-hash-tables/main.cpp @@ -1,16 +1,12 @@ /* CIS 22C - - This program builds and searches a hash table. - - Written by: Iurii Tatishchev + Hashing - Linear Probe: insert, search, and delete + Written By: Iurii Tatishchev Reviewed & Modified by: Iurii Tatishchev - IDE: CLion - - */ +*/ + #include #include -#include #include "HashTable.h" @@ -18,40 +14,47 @@ using namespace std; void buildHash(HashTable &hash); -void searchManager(HashTable &hash); +void searchManager(const HashTable &hash); + +void deleteManager(HashTable &hash); + +void insertManager(HashTable &hash); int main() { HashTable hash; - string option; buildHash(hash); - cout << "Load Factor: " << hash.getLoadFactor() << endl; - searchManager(hash); + deleteManager(hash); + insertManager(hash); return 0; } /* ************************************************** -This function builds a hash table with data from the keyboard. +This function builds a hash table with data from an array It calls the insert() function that inserts the new data at the right location in the hash table. -An input line contains the gpa of a student follow by name (assume it is a single word name) -To stop reading enter "#" ************************************************** */ void buildHash(HashTable &hash) { - string line; - cout << "Enter gpa and name [# to stop reading]:" << endl; - getline(cin, line); - while (line != "#") { - stringstream temp(line); // create a stringstream named temp with data from line - double gpa; - string name; - temp >> gpa; // read gpa from temp - temp >> name; // read name from temp - Student newStu(name, gpa); - hash.insert(newStu); - getline(cin, line); + + Student list[] = {{"Tom", 2.5}, + {"Bob", 3.2}, + {"Boc", 3.2}, + {"Linda", 3.9}, + {"Tim", 4.0}, + {"Vic", 3.9}, + {"Ann", 3.5}, + {"Dylan", 3.1}, + {"obB", 2.2}, + {"oBb", 3.7}, + {"Bbo", 3.3}, + {"bBo", 3.9}, + {"boB", 2.3}, + {"", 0}}; + + for (int i = 0; list[i].getName() != ""; i++) { + hash.insert(list[i]); } } @@ -61,19 +64,71 @@ This function searches a hash table with user provided data. It calls the hash search function in a loop. To stop searching enter "#" ************************************************** */ -void searchManager(HashTable &hash) { - string name; +void searchManager(const HashTable &hash) { + cout << endl << "~*~ Test Search ~*~" << endl; cout << "Enter name [# to stop searching]:" << endl; + string name; getline(cin, name); while (name != "#") { Student item; - int nc; - if (hash.search(item, nc, name)) { + int nc = hash.search(item, name); + if (nc != -1) { cout << item.getName() << " " << item.getGpa() << " (" << nc << " collisions!)" << endl; } else { cout << name << " not found!" << endl; } getline(cin, name); } - +} + +/* ************************************************** +This function deletes user provided data data from a hash table +It calls the hash delete function in a loop. +To stop deleting enter "#" +************************************************** */ +void deleteManager(HashTable &hash) { + cout << endl << "~*~ Test Delete ~*~" << endl; + cout << "Enter name [# to stop deleting]:" << endl; + string name; + getline(cin, name); + while (name != "#") { + Student itemOut; + if (hash.remove(itemOut, name)) { + cout << itemOut.getName() << " " << itemOut.getGpa() << " - deleted!" << endl; + } else { + cout << name << " not found!" << endl; + } + cout << "Load Factor: " << hash.getLoadFactor() << endl; + getline(cin, name); + } +} + +/* ************************************************** +This function inserts user provided data into the hash table +It rejects duplicates. +It calls hash search and hash insert in a loop. +To stop getting user input enter "#" +************************************************** */ +void insertManager(HashTable &hash) { + cout << endl << "~*~ Test Insert - reject duplicates ~*~" << endl; + cout << "Enter name [# to stop reading]:" << endl; + string name; + getline(cin, name); + while (name != "#") { + Student found; + if (hash.search(found, name) != -1) { + cout << "Duplicate key: " << found.getName() << " - rejected!" << endl; + } else { + cout << "Enter gpa:" << endl; + double gpa; + cin >> gpa; + cin.ignore(); + Student newStudent(name, gpa); + hash.insert(newStudent); + cout << name << " - inserted (" << hash.search(found, name) << " collisions)" << endl; + } + cout << "Load Factor: " << hash.getLoadFactor() << endl; + cout << "Enter name [# to stop reading]:" << endl; + getline(cin, name); + } }