fix template classes
apparently you can't have template stuff in .cpp files after all, lesson learned.
This commit is contained in:
parent
1ef6e3eef4
commit
c6243e2314
@ -1,63 +0,0 @@
|
|||||||
#include "BinarySearchTree.h"
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void BinarySearchTree<T>::insert(const T& newEntry)
|
|
||||||
{
|
|
||||||
BinaryTreeNode<T>* newNodePtr = new BinaryTreeNode<T>(newEntry);
|
|
||||||
this->rootPtr = _insert(this->rootPtr, newNodePtr);
|
|
||||||
this->count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
BinaryTreeNode<T>* BinarySearchTree<T>::_insert(BinaryTreeNode<T>* nodePtr, BinaryTreeNode<T>* newNodePtr) {
|
|
||||||
BinaryTreeNode<T>* pWalk = nodePtr, * parent = nullptr;
|
|
||||||
|
|
||||||
if (!nodePtr)
|
|
||||||
{
|
|
||||||
nodePtr = newNodePtr;
|
|
||||||
return nodePtr;
|
|
||||||
} else {
|
|
||||||
while (pWalk)
|
|
||||||
{
|
|
||||||
parent = pWalk;
|
|
||||||
if (pWalk->getItem() > newNodePtr->getItem())
|
|
||||||
pWalk = pWalk->getLeftPtr();
|
|
||||||
else
|
|
||||||
pWalk = pWalk->getRightPtr();
|
|
||||||
}
|
|
||||||
if (parent->getItem() > newNodePtr->getItem())
|
|
||||||
parent->setLeftPtr(newNodePtr);
|
|
||||||
else
|
|
||||||
parent->setRightPtr(newNodePtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool BinarySearchTree<T>::search(const T& target, T& returnedItem) const
|
|
||||||
{
|
|
||||||
BinarySearchTree<T>* temp = nullptr;
|
|
||||||
|
|
||||||
temp = _search(this->rootPtr, target);
|
|
||||||
if (temp) {
|
|
||||||
returnedItem = temp->getItem();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
BinaryTreeNode<T>* BinarySearchTree<T>::_search(BinaryTreeNode<T>* nodePtr, const T& target) const
|
|
||||||
{
|
|
||||||
BinaryTreeNode<T>* found = nullptr;
|
|
||||||
|
|
||||||
if (nodePtr) {
|
|
||||||
if (target.getCode() == nodePtr->getItem().getCode()) found = nodePtr;
|
|
||||||
else if (target.getCode() < nodePtr->getItem().getCode()) found = _search(nodePtr->getLeftPtr(), target);
|
|
||||||
else found = _search(nodePtr->getRightPtr(), target);
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
@ -20,4 +20,66 @@ public:
|
|||||||
bool search(const T& target, T& returnedItem) const;
|
bool search(const T& target, T& returnedItem) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void BinarySearchTree<T>::insert(const T& newEntry)
|
||||||
|
{
|
||||||
|
BinaryTreeNode<T>* newNodePtr = new BinaryTreeNode<T>(newEntry);
|
||||||
|
this->root = _insert(this->root, newNodePtr);
|
||||||
|
this->size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
BinaryTreeNode<T>* BinarySearchTree<T>::_insert(BinaryTreeNode<T>* nodePtr, BinaryTreeNode<T>* newNodePtr) {
|
||||||
|
BinaryTreeNode<T>* pWalk = nodePtr, * parent = nullptr;
|
||||||
|
|
||||||
|
if (!nodePtr)
|
||||||
|
{
|
||||||
|
nodePtr = newNodePtr;
|
||||||
|
return nodePtr;
|
||||||
|
} else {
|
||||||
|
while (pWalk)
|
||||||
|
{
|
||||||
|
parent = pWalk;
|
||||||
|
if (pWalk->getItem() > newNodePtr->getItem())
|
||||||
|
pWalk = pWalk->getLeftPtr();
|
||||||
|
else
|
||||||
|
pWalk = pWalk->getRightPtr();
|
||||||
|
}
|
||||||
|
if (parent->getItem() > newNodePtr->getItem())
|
||||||
|
parent->setLeftPtr(newNodePtr);
|
||||||
|
else
|
||||||
|
parent->setRightPtr(newNodePtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool BinarySearchTree<T>::search(const T& target, T& returnedItem) const
|
||||||
|
{
|
||||||
|
BinaryTreeNode<T>* temp = nullptr;
|
||||||
|
|
||||||
|
temp = _search(this->root, target);
|
||||||
|
if (temp) {
|
||||||
|
returnedItem = temp->getItem();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
BinaryTreeNode<T>* BinarySearchTree<T>::_search(BinaryTreeNode<T>* nodePtr, const T& target) const
|
||||||
|
{
|
||||||
|
BinaryTreeNode<T>* found = nullptr;
|
||||||
|
|
||||||
|
if (nodePtr) {
|
||||||
|
if (target == nodePtr->getItem()) found = nodePtr;
|
||||||
|
else if (target < nodePtr->getItem()) found = _search(nodePtr->getLeftPtr(), target);
|
||||||
|
else found = _search(nodePtr->getRightPtr(), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
#endif //INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
#endif //INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
#include "BinaryTree.h"
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void BinaryTree<T>::destroyTree(BinaryTreeNode<T>* nodePtr)
|
|
||||||
{
|
|
||||||
if (nodePtr) // != NULL
|
|
||||||
{
|
|
||||||
destroyTree(nodePtr->getLeftPtr());
|
|
||||||
destroyTree(nodePtr->getRightPtr());
|
|
||||||
delete nodePtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void BinaryTree<T>::_preorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
|
||||||
{
|
|
||||||
if (nodePtr) {
|
|
||||||
T item = nodePtr->getItem();
|
|
||||||
visit(item);
|
|
||||||
_preorder(visit, nodePtr->getLeftPtr());
|
|
||||||
_preorder(visit, nodePtr->getRightPtr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void BinaryTree<T>::_inorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
|
||||||
{
|
|
||||||
if (nodePtr) // != NULL
|
|
||||||
{
|
|
||||||
T item = nodePtr->getItem();
|
|
||||||
_inorder(visit, nodePtr->getLeftPtr());
|
|
||||||
visit(item);
|
|
||||||
_inorder(visit, nodePtr->getRightPtr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void BinaryTree<T>::_postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
|
||||||
{
|
|
||||||
if (nodePtr) {
|
|
||||||
T item = nodePtr->getItem();
|
|
||||||
_postorder(visit, nodePtr->getLeftPtr());
|
|
||||||
_postorder(visit, nodePtr->getRightPtr());
|
|
||||||
visit(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void BinaryTree<T>::_printindented(void visit(const T&, int), BinaryTreeNode<T>* nodePtr) const {
|
|
||||||
if (nodePtr) {
|
|
||||||
T item = nodePtr->getItem();
|
|
||||||
_printInnerNodes(visit, nodePtr->getLeftPtr());
|
|
||||||
if (nodePtr->getLeftPtr() || nodePtr->getRightPtr()) visit(item);
|
|
||||||
_printInnerNodes(visit, nodePtr->getRightPtr());
|
|
||||||
}
|
|
||||||
}
|
|
57
BinaryTree.h
57
BinaryTree.h
@ -13,8 +13,6 @@ public:
|
|||||||
|
|
||||||
BinaryTree() : root(nullptr), size(0) {};
|
BinaryTree() : root(nullptr), size(0) {};
|
||||||
|
|
||||||
BinaryTree(const BinaryTree<T>& tree) { }
|
|
||||||
|
|
||||||
~BinaryTree() { destroyTree(root); };
|
~BinaryTree() { destroyTree(root); };
|
||||||
|
|
||||||
[[nodiscard]] bool isEmpty() const { return size == 0; };
|
[[nodiscard]] bool isEmpty() const { return size == 0; };
|
||||||
@ -51,4 +49,59 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void BinaryTree<T>::destroyTree(BinaryTreeNode<T>* nodePtr)
|
||||||
|
{
|
||||||
|
if (nodePtr) // != NULL
|
||||||
|
{
|
||||||
|
destroyTree(nodePtr->getLeftPtr());
|
||||||
|
destroyTree(nodePtr->getRightPtr());
|
||||||
|
delete nodePtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void BinaryTree<T>::_preorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
||||||
|
{
|
||||||
|
if (nodePtr) {
|
||||||
|
T item = nodePtr->getItem();
|
||||||
|
visit(item);
|
||||||
|
_preorder(visit, nodePtr->getLeftPtr());
|
||||||
|
_preorder(visit, nodePtr->getRightPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void BinaryTree<T>::_inorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
||||||
|
{
|
||||||
|
if (nodePtr) // != NULL
|
||||||
|
{
|
||||||
|
T item = nodePtr->getItem();
|
||||||
|
_inorder(visit, nodePtr->getLeftPtr());
|
||||||
|
visit(item);
|
||||||
|
_inorder(visit, nodePtr->getRightPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void BinaryTree<T>::_postorder(void visit(const T&), BinaryTreeNode<T>* nodePtr) const
|
||||||
|
{
|
||||||
|
if (nodePtr) {
|
||||||
|
T item = nodePtr->getItem();
|
||||||
|
_postorder(visit, nodePtr->getLeftPtr());
|
||||||
|
_postorder(visit, nodePtr->getRightPtr());
|
||||||
|
visit(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void BinaryTree<T>::_printindented(void visit(const T&, int), BinaryTreeNode<T>* nodePtr) const {
|
||||||
|
if (nodePtr) {
|
||||||
|
T item = nodePtr->getItem();
|
||||||
|
_printInnerNodes(visit, nodePtr->getLeftPtr());
|
||||||
|
if (nodePtr->getLeftPtr() || nodePtr->getRightPtr()) visit(item);
|
||||||
|
_printInnerNodes(visit, nodePtr->getRightPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif //INC_08_TEAM_PROJECT_BINARYTREE_H
|
#endif //INC_08_TEAM_PROJECT_BINARYTREE_H
|
||||||
|
@ -7,17 +7,17 @@ add_executable(08_team_project main.cpp
|
|||||||
utils.h
|
utils.h
|
||||||
utils.cpp
|
utils.cpp
|
||||||
BinaryTreeNode.h
|
BinaryTreeNode.h
|
||||||
BinaryTree.cpp
|
|
||||||
BinaryTree.h
|
BinaryTree.h
|
||||||
BinarySearchTree.cpp
|
|
||||||
BinarySearchTree.h
|
BinarySearchTree.h
|
||||||
HashNode.h
|
HashNode.h
|
||||||
HashTable.h
|
HashTable.h
|
||||||
CPU.h
|
CPU.h
|
||||||
Stack.cpp
|
CPU.cpp
|
||||||
Stack.h
|
Stack.h
|
||||||
StackNode.cpp
|
|
||||||
StackNode.h
|
StackNode.h
|
||||||
fio.h
|
fio.h
|
||||||
fio.cpp
|
fio.cpp
|
||||||
|
DisplayManager.h
|
||||||
|
UndoManager.h
|
||||||
|
SearchManager.h
|
||||||
)
|
)
|
||||||
|
17
CPU.cpp
Normal file
17
CPU.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "CPU.h"
|
||||||
|
|
||||||
|
using std::string, std::ostream, std::endl;
|
||||||
|
|
||||||
|
ostream &operator<<(ostream &os, const CPU &cpu) {
|
||||||
|
os << "CPU ID: " << cpu.cpuId << std::endl;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
int key_to_index(const CPU &key, int size) {
|
||||||
|
std::string k = key.getCpuId();
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; k[i]; i++)
|
||||||
|
sum += k[i];
|
||||||
|
return sum % size;
|
||||||
|
}
|
15
CPU.h
15
CPU.h
@ -59,20 +59,13 @@ public:
|
|||||||
|
|
||||||
friend void iDisplay(const CPU &cpu, int level);
|
friend void iDisplay(const CPU &cpu, int level);
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &os, const CPU &cpu) {
|
friend std::ostream &operator<<(std::ostream &os, const CPU &cpu);
|
||||||
os << "CPU ID: " << cpu.cpuId << std::endl;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend int key_to_index(const CPU &key, int size) {
|
friend int key_to_index(const CPU &key, int size) ;
|
||||||
std::string k = key.getCpuId();
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; k[i]; i++)
|
|
||||||
sum += k[i];
|
|
||||||
return sum % size;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const CPU &cpu);
|
||||||
|
|
||||||
/*~*~*~*
|
/*~*~*~*
|
||||||
Hash function: takes the key and returns the index in the hash table
|
Hash function: takes the key and returns the index in the hash table
|
||||||
*~**/
|
*~**/
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
#include "DisplayManager.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
DisplayManager::DisplayManager(HashTable* ht, BinarySearchTree* bst) {
|
|
||||||
this->hashTable = ht;
|
|
||||||
this->bst = bst;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayManager::~DisplayManager() {
|
|
||||||
// No dynamic memory allocation, so no cleanup needed
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayManager::displayAll() const {
|
|
||||||
std::cout << "All CPUs in the database:" << std::endl;
|
|
||||||
|
|
||||||
// Iterate over the HashTable and display each CPU
|
|
||||||
for (int i = 0; i < hashTable->getSize(); i++) {
|
|
||||||
if (hashTable->getItem(i) != nullptr) {
|
|
||||||
std::cout << *(hashTable->getItem(i)) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayManager::displayTree() const {
|
|
||||||
std::cout << "CPU Binary Search Tree:" << std::endl;
|
|
||||||
|
|
||||||
// Call the BST's inorder traversal method to display the tree
|
|
||||||
bst->inorderTraversal();
|
|
||||||
}
|
|
@ -8,15 +8,49 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class DisplayManager {
|
class DisplayManager {
|
||||||
private:
|
private:
|
||||||
HashTable* hashTable;
|
HashTable<T> hashTable;
|
||||||
BinarySearchTree* bst;
|
BinarySearchTree<std::string> bst;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DisplayManager(HashTable* ht, BinarySearchTree* bst);
|
DisplayManager(HashTable<T>& ht, BinarySearchTree<std::string>& bst);
|
||||||
~DisplayManager();
|
~DisplayManager();
|
||||||
|
|
||||||
void displayAll() const;
|
void displayAll() const;
|
||||||
void displayTree() const;
|
void displayTree() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
template<typename T>
|
||||||
|
DisplayManager<T>::DisplayManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) {
|
||||||
|
this->hashTable = ht;
|
||||||
|
this->bst = bst;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
DisplayManager<T>::~DisplayManager() {
|
||||||
|
// No dynamic memory allocation, so no cleanup needed
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DisplayManager<T>::displayAll() const {
|
||||||
|
std::cout << "All CPUs in the database:" << std::endl;
|
||||||
|
|
||||||
|
// Iterate over the HashTable and display each CPU
|
||||||
|
for (int i = 0; i < hashTable.getSize(); i++) {
|
||||||
|
if (hashTable.getItem(i) != nullptr) {
|
||||||
|
std::cout << *(hashTable.getItem(i)) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DisplayManager<T>::displayTree() const {
|
||||||
|
std::cout << "CPU Binary Search Tree:" << std::endl;
|
||||||
|
|
||||||
|
// Call the BST's inorder traversal method to display the tree
|
||||||
|
// TODO: Use a proper display function
|
||||||
|
bst.inOrder([](const std::string& key) {
|
||||||
|
std::cout << key << std::endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#include "SearchManager.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
SearchManager::SearchManager(HashTable* ht) {
|
|
||||||
this->hashTable = ht;
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchManager::~SearchManager() {
|
|
||||||
// No dynamic memory allocation, so no cleanup needed
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchManager::searchCPU() const {
|
|
||||||
std::string cpuID;
|
|
||||||
std::cout << "Enter the CPU ID to search: ";
|
|
||||||
std::cin >> cpuID;
|
|
||||||
|
|
||||||
// Search for the CPU in the HashTable
|
|
||||||
CPU* foundCPU = hashTable->search(cpuID);
|
|
||||||
|
|
||||||
if (foundCPU != nullptr) {
|
|
||||||
std::cout << "CPU found:" << std::endl;
|
|
||||||
std::cout << *foundCPU << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "CPU not found." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,13 +7,34 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class SearchManager {
|
class SearchManager {
|
||||||
private:
|
private:
|
||||||
HashTable* hashTable;
|
HashTable<T> hashTable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SearchManager(HashTable* ht);
|
SearchManager(HashTable<T> &ht);
|
||||||
~SearchManager();
|
|
||||||
|
|
||||||
void searchCPU() const;
|
void searchCPU() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
template<typename T>
|
||||||
|
SearchManager<T>::SearchManager(HashTable<T> &ht) {
|
||||||
|
this->hashTable = ht;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SearchManager<T>::searchCPU() const {
|
||||||
|
std::string cpuID;
|
||||||
|
std::cout << "Enter the CPU ID to search: ";
|
||||||
|
std::cin >> cpuID;
|
||||||
|
|
||||||
|
// Search for the CPU in the HashTable
|
||||||
|
CPU *foundCPU = hashTable.search(cpuID);
|
||||||
|
|
||||||
|
if (foundCPU != nullptr) {
|
||||||
|
std::cout << "CPU found:" << std::endl;
|
||||||
|
std::cout << *foundCPU << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "CPU not found." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1 +0,0 @@
|
|||||||
#include "StackNode.h"
|
|
@ -1,37 +0,0 @@
|
|||||||
#include "UndoManager.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
UndoManager::UndoManager(HashTable* ht, BinarySearchTree* bst) {
|
|
||||||
this->hashTable = ht;
|
|
||||||
this->bst = bst;
|
|
||||||
this->undoStack = new Stack<CPU>();
|
|
||||||
}
|
|
||||||
|
|
||||||
UndoManager::~UndoManager() {
|
|
||||||
delete undoStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoManager::addToUndoStack(const CPU& cpu) {
|
|
||||||
undoStack->push(cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoManager::undoDelete() {
|
|
||||||
if (!undoStack->isEmpty()) {
|
|
||||||
CPU lastDeleted = undoStack->pop();
|
|
||||||
|
|
||||||
// Reinsert the CPU into the HashTable and BST
|
|
||||||
hashTable->insert(lastDeleted);
|
|
||||||
bst->insert(lastDeleted);
|
|
||||||
|
|
||||||
std::cout << "Undo successful. CPU reinserted:" << std::endl;
|
|
||||||
std::cout << lastDeleted << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "No deletions to undo." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoManager::clearUndoStack() {
|
|
||||||
while (!undoStack->isEmpty()) {
|
|
||||||
undoStack->pop();
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,17 +9,60 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class UndoManager {
|
class UndoManager {
|
||||||
private:
|
private:
|
||||||
HashTable* hashTable;
|
HashTable<T> hashTable;
|
||||||
BinarySearchTree* bst;
|
BinarySearchTree<std::string> bst;
|
||||||
Stack<CPU>* undoStack;
|
Stack<T> *undoStack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UndoManager(HashTable* ht, BinarySearchTree* bst);
|
UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst);
|
||||||
|
|
||||||
~UndoManager();
|
~UndoManager();
|
||||||
|
|
||||||
void addToUndoStack(const CPU& cpu);
|
void addToUndoStack(const T &cpu);
|
||||||
|
|
||||||
void undoDelete();
|
void undoDelete();
|
||||||
|
|
||||||
void clearUndoStack();
|
void clearUndoStack();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
template<typename T>
|
||||||
|
UndoManager<T>::UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) {
|
||||||
|
this->hashTable = ht;
|
||||||
|
this->bst = bst;
|
||||||
|
this->undoStack = new Stack<CPU>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
UndoManager<T>::~UndoManager() {
|
||||||
|
delete undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void UndoManager<T>::addToUndoStack(const T &cpu) {
|
||||||
|
undoStack->push(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void UndoManager<T>::undoDelete() {
|
||||||
|
if (!undoStack->isEmpty()) {
|
||||||
|
T lastDeleted = undoStack->pop();
|
||||||
|
|
||||||
|
// Reinsert the CPU into the HashTable and BST
|
||||||
|
hashTable.insert(lastDeleted, key_to_index);
|
||||||
|
bst.insert(lastDeleted.getCpuId());
|
||||||
|
|
||||||
|
std::cout << "Undo successful. CPU reinserted:" << std::endl;
|
||||||
|
std::cout << lastDeleted << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "No deletions to undo." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void UndoManager<T>::clearUndoStack() {
|
||||||
|
while (!undoStack->isEmpty()) {
|
||||||
|
undoStack->pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
50
main.cpp
50
main.cpp
@ -33,10 +33,15 @@
|
|||||||
#include "BinarySearchTree.h"
|
#include "BinarySearchTree.h"
|
||||||
#include "Stack.h"
|
#include "Stack.h"
|
||||||
#include "fio.h"
|
#include "fio.h"
|
||||||
|
#include "UndoManager.h"
|
||||||
|
#include "DisplayManager.h"
|
||||||
|
#include "SearchManager.h"
|
||||||
|
|
||||||
using std::cin, std::cout, std::string, std::vector;
|
using std::cin, std::cout, std::string, std::vector;
|
||||||
|
|
||||||
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree, Stack<CPU> &stack);
|
void processInput(char command, HashTable<CPU> &table, BinarySearchTree<string> &tree,
|
||||||
|
UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager,
|
||||||
|
SearchManager<CPU> &searchManager);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Print help table for commands
|
// Print help table for commands
|
||||||
@ -44,7 +49,11 @@ int main() {
|
|||||||
|
|
||||||
HashTable<CPU> cpuTable;
|
HashTable<CPU> cpuTable;
|
||||||
BinarySearchTree<string> cpuTree;
|
BinarySearchTree<string> cpuTree;
|
||||||
Stack<CPU> undoStack;
|
// Stack<CPU> undoStack;
|
||||||
|
|
||||||
|
DisplayManager<CPU> displayManager(cpuTable, cpuTree);
|
||||||
|
SearchManager<CPU> searchManager(cpuTable);
|
||||||
|
UndoManager<CPU> undoManager(cpuTable, cpuTree);
|
||||||
|
|
||||||
char command = ' ';
|
char command = ' ';
|
||||||
while (command != 'Q') {
|
while (command != 'Q') {
|
||||||
@ -53,7 +62,7 @@ int main() {
|
|||||||
command = toupper(command, std::locale());
|
command = toupper(command, std::locale());
|
||||||
// Temporary try catch block to handle unimplemented commands
|
// Temporary try catch block to handle unimplemented commands
|
||||||
try {
|
try {
|
||||||
processInput(command, cpuTable, cpuTree, undoStack);
|
processInput(command, cpuTable, cpuTree, undoManager, displayManager, searchManager);
|
||||||
}
|
}
|
||||||
catch (std::logic_error &e) {
|
catch (std::logic_error &e) {
|
||||||
cout << e.what() << '\n';
|
cout << e.what() << '\n';
|
||||||
@ -68,13 +77,15 @@ int main() {
|
|||||||
|
|
||||||
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||||
|
|
||||||
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree);
|
||||||
|
|
||||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager);
|
||||||
|
|
||||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack);
|
// void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager);
|
||||||
|
|
||||||
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree, Stack<CPU> &undoStack) {
|
void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<string> &cpuTree,
|
||||||
|
UndoManager<CPU> &undoManager, DisplayManager<CPU> &displayManager,
|
||||||
|
SearchManager<CPU> &searchManager) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'H':
|
case 'H':
|
||||||
printHelp();
|
printHelp();
|
||||||
@ -83,13 +94,14 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
|
|||||||
handleInsert(cpuTable, cpuTree);
|
handleInsert(cpuTable, cpuTree);
|
||||||
break;
|
break;
|
||||||
case 'F': // File input: add data from a file
|
case 'F': // File input: add data from a file
|
||||||
handleFileInput(cpuTable, cpuTree, undoStack);
|
handleFileInput(cpuTable, cpuTree);
|
||||||
|
undoManager.clearUndoStack();
|
||||||
break;
|
break;
|
||||||
case 'D': // Delete one record
|
case 'D': // Delete one record
|
||||||
deleteCPU(cpuTable, cpuTree, undoStack);
|
deleteCPU(cpuTable, cpuTree, undoManager);
|
||||||
break;
|
break;
|
||||||
case 'U': // Undo delete
|
case 'U': // Undo delete
|
||||||
undoDelete(cpuTable, cpuTree, undoStack);
|
undoManager.undoDelete();
|
||||||
break;
|
break;
|
||||||
case 'L': // List all CPUs sorted by primary key
|
case 'L': // List all CPUs sorted by primary key
|
||||||
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key");
|
||||||
@ -122,20 +134,19 @@ void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
|||||||
insertCPU(tree, hashTable);
|
insertCPU(tree, hashTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
void handleFileInput(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
|
||||||
string filename;
|
string filename;
|
||||||
cout << "Enter filename: ";
|
cout << "Enter filename: ";
|
||||||
cin >> filename;
|
cin >> filename;
|
||||||
int hashSize = findHashSize(filename);
|
int hashSize = findHashSize(filename);
|
||||||
hashTable = HashTable<CPU>(hashSize);
|
hashTable = HashTable<CPU>(hashSize);
|
||||||
tree = BinarySearchTree<string>();
|
tree = BinarySearchTree<string>();
|
||||||
undoStack = Stack<CPU>();
|
|
||||||
|
|
||||||
insertFile(filename, tree, hashTable);
|
insertFile(filename, tree, hashTable);
|
||||||
cout << "Data from file \"" << filename << "\" added.\n";
|
cout << "Data from file \"" << filename << "\" added.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, UndoManager<CPU> &undoManager) {
|
||||||
string cpuId;
|
string cpuId;
|
||||||
cout << "Enter CPU ID to delete: ";
|
cout << "Enter CPU ID to delete: ";
|
||||||
cin >> cpuId;
|
cin >> cpuId;
|
||||||
@ -147,19 +158,8 @@ void deleteCPU(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<
|
|||||||
cpu = CPU(cpuId, 0, 0, "", 0.0);
|
cpu = CPU(cpuId, 0, 0, "", 0.0);
|
||||||
}
|
}
|
||||||
hashTable.remove(cpuFound, cpu, key_to_index);
|
hashTable.remove(cpuFound, cpu, key_to_index);
|
||||||
undoStack.push(cpuFound);
|
undoManager.addToUndoStack(cpuFound);
|
||||||
tree.remove(cpuId);
|
tree.remove(cpuId);
|
||||||
|
|
||||||
cout << "CPU ID \"" << cpuId << "\" deleted.\n";
|
cout << "CPU ID \"" << cpuId << "\" deleted.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void undoDelete(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree, Stack<CPU> &undoStack) {
|
|
||||||
if (undoStack.isEmpty()) {
|
|
||||||
cout << "No deletions to undo.\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CPU cpu = undoStack.pop();
|
|
||||||
hashTable.insert(cpu, key_to_index);
|
|
||||||
tree.insert(cpu.getCpuId());
|
|
||||||
cout << "Undo deletion of CPU ID \"" << cpu.getCpuId() << "\".\n";
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user