Compare commits

..

No commits in common. "30ad8892de3f9d0b669559b3376e6b0c8d81a371" and "01d2d7f2cf9d1902e5da6affab8a09cbb24fa869" have entirely different histories.

14 changed files with 0 additions and 492 deletions

8
06-hash-tables/.idea/.gitignore generated vendored
View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -1 +0,0 @@
06_hash_tables

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/06-hash-tables.iml" filepath="$PROJECT_DIR$/.idea/06-hash-tables.iml" />
</modules>
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View File

@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.28)
project(06_hash_tables)
set(CMAKE_CXX_STANDARD 20)
add_executable(06_hash_tables main.cpp
Student.cpp)

View File

@ -1,50 +0,0 @@
// Specification file for the HashNode class
// Written By: Iurii Tatishchev
// Changed by: Iurii Tatishchev
#ifndef _HASH_NODE
#define _HASH_NODE
// To do: convert to a template
template<typename T>
class HashNode {
private:
T item;
int occupied; // 1 -> occupied, 0 -> empty from start, -1 -> empty after removal
int noCollisions;
public:
// constructors
HashNode() {
occupied = 0;
noCollisions = 0;
}
HashNode(T anItem) {
item = anItem;
occupied = 1;
noCollisions = 0;
}
HashNode(T anItem, int ocp, int nCol) {
item = anItem;
occupied = ocp;
noCollisions = nCol;
}
// setters
void setItem(const T &anItem) { item = anItem; }
void setOccupied(int ocp) { occupied = ocp; }
void setNoCollisions(int nCol) { noCollisions = nCol; }
// getters
T getItem() const { return item; }
int getOccupied() const { return occupied; }
int getNoCollisions() const { return noCollisions; }
};
#endif

View File

@ -1,81 +0,0 @@
// Implementation file for the Hash class
// Written By: Iurii Tatishchev
// Changed by: Iurii Tatishchev
#include <string>
#include <utility>
#include "HashTable.h"
using namespace std;
/*~*~*~*
A simple hash function
*~**/
int HashTable::_hash(string key) const {
int sum = 0;
for (char c : key)
sum += c;
return sum % hashSize;
};
/*~*~*~*
hash insert - linear probe
*~**/
bool HashTable::insert(const Student &itemIn) {
if (count == hashSize)
return false;
int pos = _hash(itemIn.getName());
int collisions = 0;
while (hashAry[pos].getOccupied() == 1) {
++pos;
++collisions;
pos = pos % hashSize;
}
hashAry[pos].setItem(itemIn);
hashAry[pos].setOccupied(1);
hashAry[pos].setNoCollisions(collisions);
count++;
return true;
}
/*~*~*~*
hash delete - linear probe
*~**/
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;
}
/*~*~*~*
hash search - linear probe
search for key
if found:
- copy data to itemOut
- copy number of collisions for this key to noCol
- returns true
if not found, returns false
*~**/
int HashTable::search(Student &itemOut, string key) const {
int pos = _hash(key);
for (int collisions = 0; collisions < count; collisions++) {
if (hashAry[pos].getOccupied() == 0) return -1;
if (hashAry[pos].getOccupied() == 1 && hashAry[pos].getItem().getName() == key) {
itemOut = hashAry[pos].getItem();
return hashAry[pos].getNoCollisions();
}
pos = (pos + 1) % hashSize;
}
return -1;
}

View File

@ -1,120 +0,0 @@
// Specification file for the Hash class
// Written By: Iurii Tatishchev
// Changed by: Iurii Tatishchev
#ifndef HASHTABLE_H_
#define HASHTABLE_H_
#include "HashNode.h"
template<class ItemType>
class HashTable {
private:
HashNode<ItemType> *hashAry;
int hashSize;
int count;
public:
HashTable() {
count = 0;
hashSize = 53;
hashAry = new HashNode<ItemType>[hashSize];
}
HashTable(int n) {
count = 0;
hashSize = n;
hashAry = new HashNode<ItemType>[hashSize];
}
~HashTable() { delete[] hashAry; }
int getCount() const { return count; }
int getSize() const { return hashSize; }
double getLoadFactor() const { return 100.0 * count / hashSize; }
bool isEmpty() const { return count == 0; }
bool isFull() const { return count == hashSize; }
bool insert(const ItemType &itemIn, int h(const ItemType &key, int size));
bool remove(ItemType &itemOut, const ItemType &key, int h(const ItemType &key, int size));
int search(ItemType &itemOut, const ItemType &key, int h(const ItemType &key, int size)) const;
};
/*~*~*~*
Insert an item into the hash table
It does not reject duplicates
*~**/
template<class ItemType>
bool HashTable<ItemType>::insert(const ItemType &itemIn, int h(const ItemType &key, int size)) {
if (count == hashSize)
return false;
int pos = h(itemIn, hashSize);
int collisions = 0;
while (hashAry[pos].getOccupied() == 1) {
++pos;
++collisions;
pos = pos % hashSize;
}
hashAry[pos].setItem(itemIn);
hashAry[pos].setOccupied(1);
hashAry[pos].setNoCollisions(collisions);
count++;
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<class ItemType>
bool HashTable<ItemType>::remove(ItemType &itemOut, const ItemType &key, int h(const ItemType &key, int size)) {
int pos = h(key, hashSize);
for (int collisions = 0; collisions < count; collisions++) {
if (hashAry[pos].getOccupied() == 1 && hashAry[pos].getItem() == key) {
itemOut = hashAry[pos].getItem();
// -1 means freed
hashAry[pos].setOccupied(-1);
count--;
return true;
}
pos = (pos + 1) % hashSize;
}
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<class ItemType>
int HashTable<ItemType>::search(ItemType &itemOut, const ItemType &key, int h(const ItemType &key, int size)) const {
int pos = h(key, hashSize);
for (int collisions = 0; collisions < count; collisions++) {
if (hashAry[pos].getOccupied() == 0) return -1;
if (hashAry[pos].getOccupied() == 1 && hashAry[pos].getItem() == key) {
itemOut = hashAry[pos].getItem();
return hashAry[pos].getNoCollisions();
}
pos = (pos + 1) % hashSize;
}
return -1;
}
#endif // HASHTABLE_H_

View File

@ -1,16 +0,0 @@
// Implementation file for the Student class
// Written By: Iurii Tatishchev
#include <string>
#include "Student.h"
/*~*~*~*
Hash function: takes the key and returns the index in the hash table
*~**/
int key_to_index(const Student &key, int size) {
string k = key.name;
int sum = 0;
for (int i = 0; k[i]; i++)
sum += k[i];
return sum % size;
};

View File

@ -1,46 +0,0 @@
// Specification file for the Student class
// Modified by: Iurii Tatishchev
// IDE: CLion
#ifndef STUDENT_H
#define STUDENT_H
using std::string;
class Student; // Forward Declaration
// Function Prototypes for friend functions
int key_to_index(const Student &key, int size);
class Student {
private:
double gpa;
string name;
public:
Student() {
name = "";
gpa = -1;
} // Constructor
Student(string n, double g) {
name = n;/* Write your code here */
gpa = g;
} // Overloaded Constructor
// Setters and getters
void setName(string n) { name = n; }
void setGpa(double g) { gpa = g; }
string getName() const { return name; }
double getGpa() const { return gpa; }
// Overloaded operators
bool operator==(const Student& other) { return name == other.name; }
// friend functions
friend int key_to_index(const Student& key, int size);
};
#endif

View File

@ -1,137 +0,0 @@
/*
CIS 22C
Hash Tables ADT - Linear Probe
Written By: Iurii Tatishchev
Reviewed & Modified by: Iurii Tatishchev
*/
#include <iostream>
#include "HashTable.h"
#include "Student.h"
using namespace std;
void buildHash(HashTable<Student> &hash);
void searchManager(const HashTable<Student> &hash);
void deleteManager(HashTable<Student> &hash);
void insertManager(HashTable<Student> &hash);
int main() {
HashTable<Student> hash;
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 an array
It calls the insert() function that inserts the new data at the right location in the hash table.
************************************************** */
void buildHash(HashTable<Student> &hash) {
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], key_to_index);
}
}
/* **************************************************
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(const HashTable<Student> &hash) {
cout << endl << "~*~ Test Search ~*~" << endl;
cout << "Enter name [# to stop searching]:" << endl;
string name;
getline(cin, name);
while (name != "#") {
Student item;
item.setName(name);
int nc = hash.search(item, item, key_to_index);
if (nc != -1) {
cout << item.getName() << " " << item.getGpa() << " (" << nc << " collisions!)" << endl;
} else {
cout << name << " not found!" << endl;
}
getline(cin, name);
}
cout << "Load Factor: " << hash.getLoadFactor() << endl;
}
/* **************************************************
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<Student> &hash) {
cout << endl << "~*~ Test Delete ~*~" << endl;
cout << "Enter name [# to stop deleting]:" << endl;
string name;
getline(cin, name);
while (name != "#") {
Student itemOut;
itemOut.setName(name);
if (hash.remove(itemOut, itemOut, key_to_index)) {
cout << itemOut.getName() << " " << itemOut.getGpa() << " - deleted!" << endl;
} else {
cout << name << " not found!" << endl;
}
getline(cin, name);
}
cout << "Load Factor: " << hash.getLoadFactor() << endl;
}
/* **************************************************
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<Student> &hash) {
cout << endl << "~*~ Test Insert - reject duplicates ~*~" << endl;
cout << "Enter name [# to stop reading]:" << endl;
string name;
getline(cin, name);
while (name != "#") {
Student found;
found.setName(name);
if (hash.search(found, found, key_to_index) != -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, key_to_index);
cout << name << " - inserted (" << hash.search(found, newStudent, key_to_index) << " collisions)" << endl;
}
cout << "Enter name [# to stop reading]:" << endl;
getline(cin, name);
}
cout << "Load Factor: " << hash.getLoadFactor() << endl;
}