Compare commits
10 Commits
01d2d7f2cf
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
4dbe12e593
|
|||
|
701d84242d
|
|||
|
0789614ef1
|
|||
|
cc06e5fbdb
|
|||
|
eb1cf4176f
|
|||
|
0ca7ce28fd
|
|||
|
276575ca62
|
|||
|
30ad8892de
|
|||
|
b43f08aacc
|
|||
|
3d112946f5
|
@@ -83,10 +83,6 @@ bool StudentList::insertNode(Student dataIn) {
|
||||
ListNode *newNode; // A new node
|
||||
ListNode *pCur; // To traverse the list
|
||||
|
||||
// Allocate a new node and store num there.
|
||||
newNode = new ListNode;
|
||||
newNode->stu = dataIn;
|
||||
|
||||
// Initialize pointers
|
||||
pCur = head->forw;
|
||||
|
||||
@@ -98,6 +94,10 @@ bool StudentList::insertNode(Student dataIn) {
|
||||
// Return false early if the name is a duplicate
|
||||
if (pCur->stu.name == dataIn.name) return false;
|
||||
|
||||
// Allocate a new node and store num there.
|
||||
newNode = new ListNode;
|
||||
newNode->stu = dataIn;
|
||||
|
||||
// Insert the new node between pPre and pCur
|
||||
ListNode *pPre = pCur->back; // The previous node
|
||||
pPre->forw = newNode;
|
||||
|
||||
8
06-hash-tables/.idea/.gitignore
generated
vendored
Normal file
8
06-hash-tables/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
1
06-hash-tables/.idea/.name
generated
Normal file
1
06-hash-tables/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
06_hash_tables
|
||||
2
06-hash-tables/.idea/06-hash-tables.iml
generated
Normal file
2
06-hash-tables/.idea/06-hash-tables.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
6
06-hash-tables/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
06-hash-tables/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
||||
4
06-hash-tables/.idea/misc.xml
generated
Normal file
4
06-hash-tables/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
8
06-hash-tables/.idea/modules.xml
generated
Normal file
8
06-hash-tables/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?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>
|
||||
6
06-hash-tables/.idea/vcs.xml
generated
Normal file
6
06-hash-tables/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
7
06-hash-tables/CMakeLists.txt
Normal file
7
06-hash-tables/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
project(06_hash_tables)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(06_hash_tables main.cpp
|
||||
Student.cpp)
|
||||
50
06-hash-tables/HashNode.h
Normal file
50
06-hash-tables/HashNode.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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
|
||||
81
06-hash-tables/HashTable.cpp
Normal file
81
06-hash-tables/HashTable.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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;
|
||||
}
|
||||
120
06-hash-tables/HashTable.h
Normal file
120
06-hash-tables/HashTable.h
Normal file
@@ -0,0 +1,120 @@
|
||||
// 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_
|
||||
16
06-hash-tables/Student.cpp
Normal file
16
06-hash-tables/Student.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// 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;
|
||||
};
|
||||
46
06-hash-tables/Student.h
Normal file
46
06-hash-tables/Student.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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
|
||||
137
06-hash-tables/main.cpp
Normal file
137
06-hash-tables/main.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
8
07-heaps/.idea/.gitignore
generated
vendored
Normal file
8
07-heaps/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
1
07-heaps/.idea/.name
generated
Normal file
1
07-heaps/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
07_heaps
|
||||
2
07-heaps/.idea/07-heaps.iml
generated
Normal file
2
07-heaps/.idea/07-heaps.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
6
07-heaps/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
07-heaps/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<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>
|
||||
7
07-heaps/.idea/misc.xml
generated
Normal file
7
07-heaps/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
8
07-heaps/.idea/modules.xml
generated
Normal file
8
07-heaps/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/07-heaps.iml" filepath="$PROJECT_DIR$/.idea/07-heaps.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
07-heaps/.idea/vcs.xml
generated
Normal file
6
07-heaps/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
7
07-heaps/CMakeLists.txt
Normal file
7
07-heaps/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
project(07_heaps)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(07_heaps main.cpp
|
||||
)
|
||||
13
07-heaps/Customer.cpp
Normal file
13
07-heaps/Customer.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
/* *~*~*
|
||||
Implementation file for the Customer class
|
||||
Written By: Iurii Tatishchev
|
||||
Changed by: Iurii Tatishchev
|
||||
IDE: CLion
|
||||
*~**/
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Customer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* Write your code here */
|
||||
46
07-heaps/Customer.h
Normal file
46
07-heaps/Customer.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* *~*~*
|
||||
Specification file for the Customer class
|
||||
Written By: Iurii Tatishchev
|
||||
Changed by: Iurii Tatishchev
|
||||
IDE: CLion
|
||||
*~**/
|
||||
#ifndef CUSTOMER_H_
|
||||
#define CUSTOMER_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
using std::string, std::ostream;
|
||||
|
||||
class Customer; // Forward Declaration
|
||||
|
||||
class Customer {
|
||||
private:
|
||||
int year;
|
||||
int mileage;
|
||||
int seq;
|
||||
string name;
|
||||
|
||||
int priority;
|
||||
int serial;
|
||||
|
||||
public:
|
||||
Customer() : year(0), mileage(0), seq(0), name("") {};
|
||||
|
||||
Customer(int y, int m, int s, string n) : year(y), mileage(m), seq(s), name(std::move(n)) {
|
||||
priority = calcPriority();
|
||||
serial = calcSerial();
|
||||
};
|
||||
|
||||
int calcPriority() { return mileage / 1000 + year - seq; }
|
||||
|
||||
int getSerial() const { return serial; }
|
||||
|
||||
int calcSerial() { return priority * 100 + (100 - seq); }
|
||||
|
||||
friend ostream &operator<<(ostream &os, const Customer &c) {
|
||||
os << c.year << " " << c.mileage << " (" << c.getSerial() << ") [" << c.name << "]";
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
135
07-heaps/Heap.h
Normal file
135
07-heaps/Heap.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* *~*~*
|
||||
Specification file for the Heap class: min- or max-heap of integers
|
||||
Written By: Iurii Tatishchev
|
||||
Changed by: Iurii Tatishchev
|
||||
IDE: CLion
|
||||
*~**/
|
||||
|
||||
#ifndef HEAP_H_
|
||||
#define HEAP_H_
|
||||
|
||||
template<typename T>
|
||||
class Heap {
|
||||
private:
|
||||
T *heapAry;
|
||||
int heapSize;
|
||||
int count;
|
||||
|
||||
void _reHeapUp(int lastndx, int (compareFunc)(const T&, const T&));
|
||||
|
||||
void _reHeapDown(int rootndx, int (compareFunc)(const T&, const T&));
|
||||
|
||||
int _findParent(int index) { return (index <= 0) ? (-1) : (index - 1) / 2; }
|
||||
|
||||
int _findLeftChild(int index) { return (2 * index + 1 >= count) ? (-1) : (2 * index + 1); }
|
||||
|
||||
int _findRightChild(int index) { return (2 * index + 2 >= count) ? (-1) : (2 * index + 2); }
|
||||
|
||||
public:
|
||||
Heap() {
|
||||
count = 0;
|
||||
heapSize = 128;
|
||||
heapAry = new T[heapSize];
|
||||
}
|
||||
|
||||
Heap(int n) {
|
||||
count = 0;
|
||||
heapSize = n;
|
||||
heapAry = static_cast<int *>(new T[heapSize]);
|
||||
}
|
||||
|
||||
~Heap() { delete[] heapAry; }
|
||||
|
||||
int getCount() const { return count; }
|
||||
|
||||
int getSize() const { return heapSize; }
|
||||
|
||||
bool isEmpty() const { return count == 0; }
|
||||
|
||||
bool isFull() const { return count == heapSize; }
|
||||
|
||||
bool insertHeap(T &itemIn, int (compareFunc)(const T&, const T&));
|
||||
|
||||
bool deleteHeap(T &itemOut, int (compareFunc)(const T&, const T&));
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void Heap<T>::_reHeapUp(int lastndx, int (compareFunc)(const T&, const T&)) {
|
||||
|
||||
// base case, newElement is heap's root
|
||||
if (lastndx == 0) return;
|
||||
|
||||
int parentIndex = _findParent(lastndx);
|
||||
// base case, newElement satisfies heap property
|
||||
// min heap - child not less than parent
|
||||
// max heap - child not greater than parent
|
||||
if (compareFunc(heapAry[lastndx], heapAry[parentIndex]) != -1) return;
|
||||
|
||||
// swap and continue recursing
|
||||
std::swap(heapAry[lastndx], heapAry[parentIndex]);
|
||||
_reHeapUp(parentIndex, compareFunc);
|
||||
}
|
||||
|
||||
/* *~*~*
|
||||
The private member function _reHeapDown rearranges the heap after delete by moving the
|
||||
data in the root down to the correct location in the heap
|
||||
*~**/
|
||||
template <typename T>
|
||||
void Heap<T>::_reHeapDown(int rootdex, int (compareFunc)(const T&, const T&)) {
|
||||
int maxChildIndex = -1;
|
||||
|
||||
int left = _findLeftChild(rootdex);
|
||||
int right = _findRightChild(rootdex);
|
||||
|
||||
// if there is a left child
|
||||
if (left != -1) {
|
||||
// if there is a right child that is
|
||||
// min heap - less than the left child
|
||||
// max heap - greater than the left child
|
||||
if (right != -1 && compareFunc(heapAry[right], heapAry[left]) == -1) maxChildIndex = right;
|
||||
else maxChildIndex = left;
|
||||
}
|
||||
|
||||
// base case, heap property satisfied
|
||||
// min heap - children greater than parent
|
||||
// max heap - children less than parent
|
||||
if (maxChildIndex == -1 || compareFunc(heapAry[rootdex], heapAry[maxChildIndex]) == -1) return;
|
||||
|
||||
// swap and continue recursing
|
||||
std::swap(heapAry[rootdex], heapAry[maxChildIndex]);
|
||||
_reHeapDown(maxChildIndex, compareFunc);
|
||||
}
|
||||
|
||||
/* *~*~*
|
||||
The public member function insertHeap inserts a new item into a heap.
|
||||
It calls _reheapUp.
|
||||
*~**/
|
||||
template <typename T>
|
||||
bool Heap<T>::insertHeap(T& newItem, int (compareFunc)(const T&, const T&)) {
|
||||
if (isFull()) return false;
|
||||
|
||||
heapAry[count] = newItem;
|
||||
_reHeapUp(count, compareFunc);
|
||||
count++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* *~*~*
|
||||
The public member function deleteHeap deletes the root of the heap and
|
||||
passes back the root's data. It calls _reheapDown.
|
||||
*~**/
|
||||
template <typename T>
|
||||
bool Heap<T>::deleteHeap(T& returnItem, int (compareFunc)(const T&, const T&)) {
|
||||
if (isEmpty()) return false;
|
||||
|
||||
returnItem = heapAry[0];
|
||||
heapAry[0] = heapAry[count - 1];
|
||||
count--;
|
||||
_reHeapDown(0, compareFunc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
105
07-heaps/main.cpp
Normal file
105
07-heaps/main.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
Heaps - ADT
|
||||
|
||||
This program will read data about overbooked customers,
|
||||
find their priority and serial numbers, build a heap, then display
|
||||
customers in priority sequence
|
||||
|
||||
Written By: Iurii Tatishchev
|
||||
Changed By: Iurii Tatishchev
|
||||
IDE: CLion
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "Customer.h"
|
||||
#include "Heap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Function Prototypes
|
||||
int compareCustomer(const Customer &c1, const Customer &c2);
|
||||
|
||||
void processArrival(Heap<Customer> &heap, ifstream &inputFile, int seq);
|
||||
|
||||
void processServe(Heap<Customer> &heap);
|
||||
|
||||
void displayRejected(Heap<Customer> &heap);
|
||||
|
||||
int main() {
|
||||
// Get input file name
|
||||
string inputFileName;
|
||||
cout << "Input file name: ";
|
||||
getline(cin, inputFileName);
|
||||
cout << endl;
|
||||
|
||||
// Open input file
|
||||
ifstream inputFile(inputFileName);
|
||||
if (!inputFile.good()) {
|
||||
cerr << "Error: could not open file " << inputFileName << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create heap
|
||||
Heap<Customer> heap;
|
||||
|
||||
// Process input file
|
||||
char command;
|
||||
int seq = 1;
|
||||
while (inputFile >> command) {
|
||||
switch (command) {
|
||||
case 'A':
|
||||
processArrival(heap, inputFile, seq);
|
||||
seq++;
|
||||
break;
|
||||
case 'S':
|
||||
processServe(heap);
|
||||
break;
|
||||
default:
|
||||
cerr << "Error: invalid command " << command << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
cout << "Served overbooked customers: " << seq - heap.getCount() - 1 << "\n\n";
|
||||
|
||||
// Display rejected customers
|
||||
int rejectedCustomers = heap.getCount();
|
||||
displayRejected(heap);
|
||||
cout << "Rejected overbooked customers: " << rejectedCustomers << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compareCustomer(const Customer &c1, const Customer &c2) {
|
||||
if (c1.getSerial() < c2.getSerial()) return 1;
|
||||
if (c1.getSerial() > c2.getSerial()) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void processArrival(Heap<Customer> &heap, ifstream &inputFile, int seq) {
|
||||
int years, mileage;
|
||||
string name;
|
||||
inputFile >> years >> mileage;
|
||||
getline(inputFile >> ws, name);
|
||||
Customer customer(years, mileage, seq, name);
|
||||
heap.insertHeap(customer, compareCustomer);
|
||||
}
|
||||
|
||||
void processServe(Heap<Customer> &heap) {
|
||||
if (heap.isEmpty()) {
|
||||
cout << "Heap is empty" << endl;
|
||||
return;
|
||||
}
|
||||
Customer customer;
|
||||
heap.deleteHeap(customer, compareCustomer);
|
||||
cout << customer << endl;
|
||||
}
|
||||
|
||||
void displayRejected(Heap<Customer> &heap) {
|
||||
Customer customer;
|
||||
while (!heap.isEmpty()) {
|
||||
heap.deleteHeap(customer, compareCustomer);
|
||||
cout << customer << endl;
|
||||
}
|
||||
}
|
||||
30
07-heaps/overbooked.txt
Normal file
30
07-heaps/overbooked.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
A 5 53000 Robert Hill
|
||||
A 3 89000 Amanda Trapp
|
||||
A 3 90000 Jonathan Nguyen
|
||||
A 5 56000 Tom Martin
|
||||
A 1 21000 Mary Lou Gilley
|
||||
S
|
||||
S
|
||||
S
|
||||
A 3 89000 Bob Che
|
||||
A 7 72000 Warren Rexroad
|
||||
A 2 65000 Vincent Gonzales
|
||||
A 3 34000 Paula Hung
|
||||
S
|
||||
S
|
||||
A 6 21000 Lou Masson
|
||||
A 4 42000 Steve Chu
|
||||
A 3 99000 Linda Lee
|
||||
S
|
||||
S
|
||||
A 3 69000 Dave Lightfoot
|
||||
A 3 83000 Daniel Oh
|
||||
A 5 50000 Sue Andrews
|
||||
A 2 73000 Joanne Brown
|
||||
S
|
||||
A 7 96000 Paul Ng
|
||||
S
|
||||
A 5 53000 Steven Chen
|
||||
A 2 65000 Vladimir Johnson
|
||||
S
|
||||
A 7 72000 Peter Edwards
|
||||
21
07-heaps/overbooked_1.txt
Normal file
21
07-heaps/overbooked_1.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
A 5 53000 Robert Hill
|
||||
A 3 89000 Amanda Trapp
|
||||
A 3 90000 Jonathan Nguyen
|
||||
A 5 56000 Tom Martin
|
||||
A 1 21000 Mary Lou Gilley
|
||||
A 3 89000 Bob Che
|
||||
A 7 72000 Warren Rexroad
|
||||
A 6 21000 Lou Masson
|
||||
A 2 65000 Vincent Gonzales
|
||||
A 3 34000 Paula Hung
|
||||
A 4 42000 Steve Chu
|
||||
A 3 99000 Linda Lee
|
||||
A 3 69000 Dave Lightfoot
|
||||
A 3 83000 Daniel Oh
|
||||
A 5 50000 Sue Andrews
|
||||
A 2 73000 Joanne Brown
|
||||
A 7 96000 Paul Ng
|
||||
A 5 53000 Steven Chen
|
||||
A 2 65000 Vladimir Johnson
|
||||
A 7 72000 Peter Edwards
|
||||
A 6 21000 Zoe Smith
|
||||
10
07-heaps/overbooked_2.txt
Normal file
10
07-heaps/overbooked_2.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
A 5 53000 Robert Hill
|
||||
A 3 89000 Amanda Trapp
|
||||
A 2 65000 Vincent Gonzales
|
||||
S
|
||||
A 3 34000 Paula Hung
|
||||
A 4 42000 Steve Chu
|
||||
S
|
||||
A 2 65000 Vladimir Johnson
|
||||
S
|
||||
A 7 72000 Warren Rexroad
|
||||
5
07-heaps/test.txt
Normal file
5
07-heaps/test.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
A 5 53000 Robert Hill
|
||||
A 3 89000 Amanda Trapp
|
||||
A 3 90000 Jonathan Nguyen
|
||||
S
|
||||
A 5 56000 Tom Martin
|
||||
Reference in New Issue
Block a user