Compare commits
17 Commits
5b5e2b6d67
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
4dbe12e593
|
|||
|
701d84242d
|
|||
|
0789614ef1
|
|||
|
cc06e5fbdb
|
|||
|
eb1cf4176f
|
|||
|
0ca7ce28fd
|
|||
|
276575ca62
|
|||
|
30ad8892de
|
|||
|
b43f08aacc
|
|||
|
3d112946f5
|
|||
|
01d2d7f2cf
|
|||
|
42ba63e654
|
|||
|
0bc2b9690f
|
|||
|
8e55246e9c
|
|||
|
2ff40ef4e9
|
|||
|
41c45e09fb
|
|||
|
6f5d2f2d5e
|
@@ -83,10 +83,6 @@ bool StudentList::insertNode(Student dataIn) {
|
|||||||
ListNode *newNode; // A new node
|
ListNode *newNode; // A new node
|
||||||
ListNode *pCur; // To traverse the list
|
ListNode *pCur; // To traverse the list
|
||||||
|
|
||||||
// Allocate a new node and store num there.
|
|
||||||
newNode = new ListNode;
|
|
||||||
newNode->stu = dataIn;
|
|
||||||
|
|
||||||
// Initialize pointers
|
// Initialize pointers
|
||||||
pCur = head->forw;
|
pCur = head->forw;
|
||||||
|
|
||||||
@@ -98,6 +94,10 @@ bool StudentList::insertNode(Student dataIn) {
|
|||||||
// Return false early if the name is a duplicate
|
// Return false early if the name is a duplicate
|
||||||
if (pCur->stu.name == dataIn.name) return false;
|
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
|
// Insert the new node between pPre and pCur
|
||||||
ListNode *pPre = pCur->back; // The previous node
|
ListNode *pPre = pCur->back; // The previous node
|
||||||
pPre->forw = newNode;
|
pPre->forw = newNode;
|
||||||
|
|||||||
8
05-trees/.idea/.gitignore
generated
vendored
Normal file
8
05-trees/.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
05-trees/.idea/.name
generated
Normal file
1
05-trees/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
05_trees
|
||||||
2
05-trees/.idea/05-trees.iml
generated
Normal file
2
05-trees/.idea/05-trees.iml
generated
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||||
6
05-trees/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
05-trees/.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
05-trees/.idea/misc.xml
generated
Normal file
4
05-trees/.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
05-trees/.idea/modules.xml
generated
Normal file
8
05-trees/.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/05-trees.iml" filepath="$PROJECT_DIR$/.idea/05-trees.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
05-trees/.idea/vcs.xml
generated
Normal file
6
05-trees/.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>
|
||||||
46
05-trees/BinaryNode.h
Normal file
46
05-trees/BinaryNode.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef _BINARY_NODE
|
||||||
|
#define _BINARY_NODE
|
||||||
|
|
||||||
|
template<class ItemType>
|
||||||
|
class BinaryNode {
|
||||||
|
private:
|
||||||
|
ItemType item; // Data portion
|
||||||
|
BinaryNode<ItemType> *leftPtr; // Pointer to left child
|
||||||
|
BinaryNode<ItemType> *rightPtr; // Pointer to right child
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
BinaryNode(const ItemType &anItem) {
|
||||||
|
item = anItem;
|
||||||
|
leftPtr = 0;
|
||||||
|
rightPtr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryNode(const ItemType &anItem,
|
||||||
|
BinaryNode<ItemType> *left,
|
||||||
|
BinaryNode<ItemType> *right) {
|
||||||
|
item = anItem;
|
||||||
|
leftPtr = left;
|
||||||
|
rightPtr = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setters
|
||||||
|
void setItem(const ItemType &anItem) { item = anItem; }
|
||||||
|
|
||||||
|
void setLeftPtr(BinaryNode<ItemType> *left) { leftPtr = left; }
|
||||||
|
|
||||||
|
void setRightPtr(BinaryNode<ItemType> *right) { rightPtr = right; }
|
||||||
|
|
||||||
|
// getters
|
||||||
|
ItemType getItem() const { return item; }
|
||||||
|
|
||||||
|
BinaryNode<ItemType> *getLeftPtr() const { return leftPtr; }
|
||||||
|
|
||||||
|
BinaryNode<ItemType> *getRightPtr() const { return rightPtr; }
|
||||||
|
|
||||||
|
// other functions
|
||||||
|
bool isLeaf() const { return (leftPtr == 0 && rightPtr == 0); }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
163
05-trees/BinarySearchTree.h
Normal file
163
05-trees/BinarySearchTree.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
// Binary Search Tree ADT
|
||||||
|
// Created by Iurii Tatishchev
|
||||||
|
// Modified by: Iurii Tatishchev
|
||||||
|
|
||||||
|
#ifndef _BINARY_SEARCH_TREE
|
||||||
|
#define _BINARY_SEARCH_TREE
|
||||||
|
|
||||||
|
#include "BinaryTree.h"
|
||||||
|
|
||||||
|
template<class ItemType>
|
||||||
|
class BinarySearchTree : public BinaryTree<ItemType> {
|
||||||
|
public:
|
||||||
|
// insert a node at the correct location
|
||||||
|
bool insert(const ItemType &item);
|
||||||
|
|
||||||
|
// remove a node if found
|
||||||
|
// bool remove(const ItemType &item);
|
||||||
|
// find a target node
|
||||||
|
bool search(const ItemType &target, ItemType &returnedItem) const;
|
||||||
|
|
||||||
|
// find the smallest node
|
||||||
|
bool findSmallest(ItemType &returnedItem) const;
|
||||||
|
|
||||||
|
// find the largest node
|
||||||
|
bool findLargest(ItemType &returnedItem) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// internal insert node: insert newNode in nodePtr subtree
|
||||||
|
BinaryNode<ItemType> *_insert(BinaryNode<ItemType> *nodePtr, BinaryNode<ItemType> *newNode);
|
||||||
|
|
||||||
|
// search for target node
|
||||||
|
BinaryNode<ItemType> *_search(BinaryNode<ItemType> *treePtr, const ItemType &target) const;
|
||||||
|
|
||||||
|
// find the smallest node
|
||||||
|
BinaryNode<ItemType> *_findSmallest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const;
|
||||||
|
|
||||||
|
// find the largest node
|
||||||
|
BinaryNode<ItemType> *_findLargest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const;
|
||||||
|
|
||||||
|
// internal remove node: locate and delete target node under nodePtr subtree
|
||||||
|
// BinaryNode<ItemType>* _remove(BinaryNode<ItemType>* nodePtr, const ItemType target, bool &success);
|
||||||
|
|
||||||
|
// delete target node from tree, called by internal remove node
|
||||||
|
// BinaryNode<ItemType>* _removeNode(BinaryNode<ItemType>* targetNodePtr);
|
||||||
|
|
||||||
|
// remove the leftmost node in the left subtree of nodePtr
|
||||||
|
// BinaryNode<ItemType>* _removeLeftmostNode(BinaryNode<ItemType>* nodePtr, ItemType &successor);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////// public function definitions ///////////////////////////
|
||||||
|
// Wrapper for _insert - Inserting items within a tree
|
||||||
|
template<class ItemType>
|
||||||
|
bool BinarySearchTree<ItemType>::insert(const ItemType &newEntry) {
|
||||||
|
auto *newNodePtr = new BinaryNode<ItemType>(newEntry);
|
||||||
|
this->rootPtr = _insert(this->rootPtr, newNodePtr);
|
||||||
|
this->count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finding the smallest, which is the leftmost leaf (wrapper function)
|
||||||
|
template<class ItemType>
|
||||||
|
bool BinarySearchTree<ItemType>::findSmallest(ItemType &returnedItem) const {
|
||||||
|
BinaryNode<ItemType> *temp = nullptr;
|
||||||
|
temp = _findSmallest(this->rootPtr, returnedItem);
|
||||||
|
return temp != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finding the largest, which is the rightmost leaf (wrapper function)
|
||||||
|
template<class ItemType>
|
||||||
|
bool BinarySearchTree<ItemType>::findLargest(ItemType &returnedItem) const {
|
||||||
|
BinaryNode<ItemType> *temp = nullptr;
|
||||||
|
temp = _findLargest(this->rootPtr, returnedItem);
|
||||||
|
return temp != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for _search
|
||||||
|
// - it calls the private _search function that returns a Node pointer or NULL
|
||||||
|
// - if found, it copies data from that node and sends it back to the caller
|
||||||
|
// via the output parameter, and returns true, otherwise it returns false.
|
||||||
|
template<class ItemType>
|
||||||
|
bool BinarySearchTree<ItemType>::search(const ItemType &anEntry, ItemType &returnedItem) const {
|
||||||
|
BinaryNode<ItemType> *temp = nullptr;
|
||||||
|
temp = _search(this->rootPtr, anEntry);
|
||||||
|
|
||||||
|
if (temp != nullptr) {
|
||||||
|
returnedItem = temp->getItem();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////// private functions ////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Recursive implementation of the insert operation
|
||||||
|
template<class ItemType>
|
||||||
|
BinaryNode<ItemType> *BinarySearchTree<ItemType>::_insert(BinaryNode<ItemType> *nodePtr,
|
||||||
|
BinaryNode<ItemType> *newNodePtr) {
|
||||||
|
// Base case: tree is empty
|
||||||
|
if (nodePtr == nullptr) return newNodePtr;
|
||||||
|
|
||||||
|
// Inserting larger item to the right:
|
||||||
|
if (nodePtr->getItem() < newNodePtr->getItem()) {
|
||||||
|
// Recurse if right child is not null
|
||||||
|
if (nodePtr->getRightPtr() != nullptr)
|
||||||
|
_insert(nodePtr->getRightPtr(), newNodePtr);
|
||||||
|
// Otherwise, insert the new node
|
||||||
|
else nodePtr->setRightPtr(newNodePtr);
|
||||||
|
}
|
||||||
|
// Inserting smaller item to the left:
|
||||||
|
else {
|
||||||
|
// Recurse if left child is not null
|
||||||
|
if (nodePtr->getLeftPtr() != nullptr)
|
||||||
|
_insert(nodePtr->getLeftPtr(), newNodePtr);
|
||||||
|
// Otherwise, insert the new node
|
||||||
|
else nodePtr->setLeftPtr(newNodePtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the root node
|
||||||
|
return nodePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation to find the smallest: recursive
|
||||||
|
template<class ItemType>
|
||||||
|
BinaryNode<ItemType> *
|
||||||
|
BinarySearchTree<ItemType>::_findSmallest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const {
|
||||||
|
if (nodePtr->getLeftPtr() == nullptr) {
|
||||||
|
smallest = nodePtr->getItem();
|
||||||
|
return nodePtr;
|
||||||
|
}
|
||||||
|
return _findSmallest(nodePtr->getLeftPtr(), smallest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation to find the largest: recursive
|
||||||
|
template<class ItemType>
|
||||||
|
BinaryNode<ItemType> *BinarySearchTree<ItemType>::_findLargest(BinaryNode<ItemType> *nodePtr, ItemType &biggest) const {
|
||||||
|
if (nodePtr->getRightPtr() == nullptr) {
|
||||||
|
biggest = nodePtr->getItem();
|
||||||
|
return nodePtr;
|
||||||
|
}
|
||||||
|
return _findLargest(nodePtr->getRightPtr(), biggest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive implementation of the search operation
|
||||||
|
// - return NULL if target not found, otherwise
|
||||||
|
// - returns a pointer to the node that matched the target
|
||||||
|
template<class ItemType>
|
||||||
|
BinaryNode<ItemType> *BinarySearchTree<ItemType>::_search(BinaryNode<ItemType> *nodePtr,
|
||||||
|
const ItemType &target) const {
|
||||||
|
// Two base cases: root is NULL or target is found
|
||||||
|
if (nodePtr == nullptr) return nullptr;
|
||||||
|
if (nodePtr->getItem() == target) return nodePtr;
|
||||||
|
|
||||||
|
// Recursive cases, search either left or right subtree based on the target
|
||||||
|
if (target < nodePtr->getItem()) return _search(nodePtr->getLeftPtr(), target);
|
||||||
|
if (target > nodePtr->getItem()) return _search(nodePtr->getRightPtr(), target);
|
||||||
|
|
||||||
|
// To prevent compiler warning
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
139
05-trees/BinaryTree.h
Normal file
139
05-trees/BinaryTree.h
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
// Binary tree abstract base class
|
||||||
|
// Created by Iurii Tatishchev
|
||||||
|
// Modified by: Iurii Tatishchev
|
||||||
|
|
||||||
|
#ifndef _BINARY_TREE
|
||||||
|
#define _BINARY_TREE
|
||||||
|
|
||||||
|
#include "BinaryNode.h"
|
||||||
|
|
||||||
|
template<class ItemType>
|
||||||
|
class BinaryTree {
|
||||||
|
protected:
|
||||||
|
BinaryNode<ItemType> *rootPtr; // ptr to root node
|
||||||
|
int count; // number of nodes in tree
|
||||||
|
|
||||||
|
public:
|
||||||
|
// "admin" functions
|
||||||
|
BinaryTree() {
|
||||||
|
rootPtr = nullptr;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryTree(const BinaryTree<ItemType> &tree) {}
|
||||||
|
|
||||||
|
virtual ~BinaryTree() { destroyTree(rootPtr); }
|
||||||
|
|
||||||
|
// common functions for all binary trees
|
||||||
|
bool isEmpty() const { return count == 0; }
|
||||||
|
|
||||||
|
int getCount() const { return count; }
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
destroyTree(rootPtr);
|
||||||
|
rootPtr = nullptr;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void preOrder(void visit(const ItemType &)) const { _preorder(visit, rootPtr); }
|
||||||
|
|
||||||
|
void inOrder(void visit(const ItemType &)) const { _inorder(visit, rootPtr); }
|
||||||
|
|
||||||
|
void postOrder(void visit(const ItemType &)) const { _postorder(visit, rootPtr); }
|
||||||
|
|
||||||
|
void printTree(void visit(const ItemType &, int)) const { _printTree(visit, rootPtr, 1); }
|
||||||
|
|
||||||
|
void printInnerNodes(void visit(const ItemType &)) const { _printInnerNodes(visit, rootPtr); }
|
||||||
|
|
||||||
|
// abstract functions to be implemented by derived class
|
||||||
|
virtual bool insert(const ItemType &newData) = 0;
|
||||||
|
|
||||||
|
//virtual bool remove(const ItemType &data) = 0;
|
||||||
|
virtual bool search(const ItemType &target, ItemType &returnedItem) const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// delete all nodes from the tree
|
||||||
|
void destroyTree(BinaryNode<ItemType> *nodePtr);
|
||||||
|
|
||||||
|
// internal traverse
|
||||||
|
void _preorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
|
||||||
|
|
||||||
|
void _inorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
|
||||||
|
|
||||||
|
void _postorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
|
||||||
|
|
||||||
|
void _printTree(void visit(const ItemType &, int), BinaryNode<ItemType> *nodePtr, int level) const;
|
||||||
|
|
||||||
|
void _printInnerNodes(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Destroy the entire tree
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::destroyTree(BinaryNode<ItemType> *nodePtr) {
|
||||||
|
if (nodePtr) // != NULL
|
||||||
|
{
|
||||||
|
destroyTree(nodePtr->getLeftPtr());
|
||||||
|
destroyTree(nodePtr->getRightPtr());
|
||||||
|
// cout << "DEBUG - Destructor: Now deleting " << nodePtr->getItem().getName() << endl;
|
||||||
|
delete nodePtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preorder Traversal
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::_preorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
|
||||||
|
if (nodePtr == nullptr) return;
|
||||||
|
|
||||||
|
ItemType item = nodePtr->getItem();
|
||||||
|
visit(item);
|
||||||
|
_preorder(visit, nodePtr->getLeftPtr());
|
||||||
|
_preorder(visit, nodePtr->getRightPtr());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inorder Traversal
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::_inorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
|
||||||
|
if (nodePtr) // != NULL
|
||||||
|
{
|
||||||
|
ItemType item = nodePtr->getItem();
|
||||||
|
_inorder(visit, nodePtr->getLeftPtr());
|
||||||
|
visit(item);
|
||||||
|
_inorder(visit, nodePtr->getRightPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Postorder Traversal
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::_postorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
|
||||||
|
if (nodePtr == nullptr) return;
|
||||||
|
|
||||||
|
_postorder(visit, nodePtr->getLeftPtr());
|
||||||
|
_postorder(visit, nodePtr->getRightPtr());
|
||||||
|
ItemType item = nodePtr->getItem();
|
||||||
|
visit(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints tree as an indented list
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::_printTree(void visit(const ItemType &, int), BinaryNode<ItemType> *nodePtr, int level) const {
|
||||||
|
if (nodePtr == nullptr) return;
|
||||||
|
|
||||||
|
ItemType item = nodePtr->getItem();
|
||||||
|
visit(item, level);
|
||||||
|
_printTree(visit, nodePtr->getRightPtr(), level + 1);
|
||||||
|
_printTree(visit, nodePtr->getLeftPtr(), level + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints inner nodes
|
||||||
|
template<class ItemType>
|
||||||
|
void BinaryTree<ItemType>::_printInnerNodes(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
|
||||||
|
if (nodePtr == nullptr || nodePtr->isLeaf()) return;
|
||||||
|
|
||||||
|
ItemType item = nodePtr->getItem();
|
||||||
|
_printInnerNodes(visit, nodePtr->getLeftPtr());
|
||||||
|
visit(item);
|
||||||
|
_printInnerNodes(visit, nodePtr->getRightPtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
11
05-trees/CMakeLists.txt
Normal file
11
05-trees/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.28)
|
||||||
|
project(05_trees)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_executable(05_trees main.cpp
|
||||||
|
BinaryTree.h
|
||||||
|
BinaryNode.h
|
||||||
|
BinarySearchTree.h
|
||||||
|
Park.cpp
|
||||||
|
Park.h)
|
||||||
80
05-trees/Park.cpp
Normal file
80
05-trees/Park.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
// Implementation file for the Park class
|
||||||
|
// Written By: Iurii Tatishchev
|
||||||
|
// Reviewed By: Iurii Tatishchev
|
||||||
|
// IDE: CLion
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Park.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// **************************************************
|
||||||
|
// Constructor
|
||||||
|
// **************************************************
|
||||||
|
Park::Park() {
|
||||||
|
code = "";
|
||||||
|
state = "";
|
||||||
|
name = "";
|
||||||
|
description = "";
|
||||||
|
year = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **************************************************
|
||||||
|
// Overloaded Constructor
|
||||||
|
// **************************************************
|
||||||
|
Park::Park(string cd, string st, string nm, string dsc, int yr) {
|
||||||
|
code = cd;
|
||||||
|
state = st;
|
||||||
|
name = nm;
|
||||||
|
description = dsc;
|
||||||
|
year = yr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Friend Functions Definitions
|
||||||
|
|
||||||
|
// ***********************************************************
|
||||||
|
// hDisplay
|
||||||
|
// Displays code, state, and year data members of a Park object
|
||||||
|
// on one line (horizontal display)
|
||||||
|
// ***********************************************************
|
||||||
|
void hDisplay(const Park &item) {
|
||||||
|
cout << item.code << " ";
|
||||||
|
cout << item.state << " ";
|
||||||
|
cout << item.year << " ";
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***********************************************************
|
||||||
|
// vDisplay
|
||||||
|
// Displays name, description, state, and year of a Park object
|
||||||
|
// one per line (vertical display)
|
||||||
|
// ***********************************************************
|
||||||
|
void vDisplay(const Park &item) {
|
||||||
|
cout << " Name: " << item.name << endl;
|
||||||
|
cout << "Description: " << item.description << endl;
|
||||||
|
cout << " State: " << item.state << endl;
|
||||||
|
cout << " Year: " << item.year << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***********************************************************
|
||||||
|
// iDisplay
|
||||||
|
// on one line, including the level number and
|
||||||
|
// ".." for each indentation level
|
||||||
|
// ***********************************************************
|
||||||
|
void iDisplay(const Park &item, int level) {
|
||||||
|
for (int i = 1; i < level; i++)
|
||||||
|
cout << "..";
|
||||||
|
cout << level << "). " << item.code << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***********************************************************
|
||||||
|
// kDisplay
|
||||||
|
// Displays the key: code of a Park object
|
||||||
|
// on one line (key display)
|
||||||
|
// ***********************************************************
|
||||||
|
void kDisplay(const Park &park) {
|
||||||
|
cout << park.code << "\n";
|
||||||
|
}
|
||||||
88
05-trees/Park.h
Normal file
88
05-trees/Park.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// Specification file for the Park class
|
||||||
|
// Written By: Iurii Tatishchev
|
||||||
|
// Reviewed by: Iurii Tatishchev
|
||||||
|
// IDE: CLion
|
||||||
|
|
||||||
|
#ifndef PARK_H
|
||||||
|
#define PARK_H
|
||||||
|
|
||||||
|
// #include<iostream>
|
||||||
|
#include<string>
|
||||||
|
// #include<cstdlib>
|
||||||
|
|
||||||
|
// using namespace std;
|
||||||
|
// ^^^^^ This statement
|
||||||
|
// in a header file of a complex project could create
|
||||||
|
// namespace management problems for the entire project
|
||||||
|
// (such as name collisions).
|
||||||
|
// Do not write using namespace at the top level in a header file!
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
class Park {
|
||||||
|
private:
|
||||||
|
string code; // the unique park identifier
|
||||||
|
string state;
|
||||||
|
string name;
|
||||||
|
string description;
|
||||||
|
int year;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
Park();
|
||||||
|
|
||||||
|
Park(string, string, string, string, int);
|
||||||
|
|
||||||
|
// setters
|
||||||
|
void setCode(string cd) { code = cd; }
|
||||||
|
|
||||||
|
void setState(string st) { state = st; }
|
||||||
|
|
||||||
|
void setName(string nm) { name = nm; }
|
||||||
|
|
||||||
|
void setDesc(int dsc) { description = dsc; }
|
||||||
|
|
||||||
|
void setYear(int yr) { year = yr; }
|
||||||
|
|
||||||
|
// getters
|
||||||
|
string getCode() const { return code; }
|
||||||
|
|
||||||
|
string getState() const { return state; }
|
||||||
|
|
||||||
|
string getName() const { return name; }
|
||||||
|
|
||||||
|
string getDesc() const { return description; }
|
||||||
|
|
||||||
|
int getYear() const { return year; }
|
||||||
|
|
||||||
|
/* overloaded operators
|
||||||
|
- the stream insertion operator ( << )
|
||||||
|
- the relational operators (<, >, == )
|
||||||
|
*/
|
||||||
|
friend std::ostream &operator<<(std::ostream &out, const Park &park);
|
||||||
|
|
||||||
|
bool operator<(const Park &park) const { return code < park.code; }
|
||||||
|
|
||||||
|
bool operator>(const Park &park) const { return code > park.code; }
|
||||||
|
|
||||||
|
bool operator==(const Park &park) const { return code == park.code; }
|
||||||
|
|
||||||
|
// friend functions
|
||||||
|
friend void hDisplay(const Park &);
|
||||||
|
|
||||||
|
friend void vDisplay(const Park &);
|
||||||
|
|
||||||
|
friend void iDisplay(const Park &item, int level);
|
||||||
|
|
||||||
|
friend void kDisplay(const Park &item);
|
||||||
|
};
|
||||||
|
|
||||||
|
void hDisplay(const Park &);
|
||||||
|
|
||||||
|
void vDisplay(const Park &);
|
||||||
|
|
||||||
|
void iDisplay(const Park &item, int level);
|
||||||
|
|
||||||
|
void kDisplay(const Park &item);
|
||||||
|
|
||||||
|
#endif
|
||||||
152
05-trees/main.cpp
Normal file
152
05-trees/main.cpp
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
// BST ADT
|
||||||
|
// Created by Iurii Tatishchev
|
||||||
|
// Modified by: Iurii Tatishchev
|
||||||
|
|
||||||
|
#include "BinarySearchTree.h"
|
||||||
|
#include "Park.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void displayManager(const BinarySearchTree<Park> &bst);
|
||||||
|
|
||||||
|
void buildBST(const string &filename, BinarySearchTree<Park> &bst);
|
||||||
|
|
||||||
|
void searchManager(const BinarySearchTree<Park> &bst);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
string filename;
|
||||||
|
BinarySearchTree<Park> bst;
|
||||||
|
|
||||||
|
cout << "What is the input file's name? ";
|
||||||
|
getline(cin, filename);
|
||||||
|
buildBST(filename, bst);
|
||||||
|
displayManager(bst);
|
||||||
|
searchManager(bst);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Display manager: traversals, count, indented tree, and inner nodes
|
||||||
|
Input Parameter: bst
|
||||||
|
*/
|
||||||
|
void displayManager(const BinarySearchTree<Park> &bst) {
|
||||||
|
|
||||||
|
string option;
|
||||||
|
|
||||||
|
// count
|
||||||
|
cout << "Display count [Y/N]?" << endl;
|
||||||
|
getline(cin, option);
|
||||||
|
option[0] = toupper(option[0]);
|
||||||
|
if (option == "Y") {
|
||||||
|
cout << "The number of nodes in the BST is ";
|
||||||
|
cout << bst.getCount() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// traversals
|
||||||
|
cout << "Display Tree [In/Pre/posT/N]?" << endl;
|
||||||
|
getline(cin, option); // I, P, T or N
|
||||||
|
option[0] = toupper(option[0]);
|
||||||
|
switch (option[0]) {
|
||||||
|
case 'I':
|
||||||
|
cout << endl << "Inorder:" << endl;
|
||||||
|
bst.inOrder(hDisplay);
|
||||||
|
cout << endl;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
cout << endl << "Preorder:" << endl;
|
||||||
|
bst.preOrder(hDisplay);
|
||||||
|
cout << endl;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
cout << endl << "Postorder:" << endl;
|
||||||
|
bst.postOrder(hDisplay);
|
||||||
|
cout << endl;
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cout << "Invalid option!" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indented Tree
|
||||||
|
cout << "Display Indented List [Y/N]?" << endl;
|
||||||
|
getline(cin, option);
|
||||||
|
option[0] = toupper(option[0]);
|
||||||
|
if (option == "Y") {
|
||||||
|
cout << "Indented List:" << endl;
|
||||||
|
bst.printTree(iDisplay);
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inner Nodes
|
||||||
|
cout << "Display Inner Nodes [Y/N]?" << endl;
|
||||||
|
getline(cin, option);
|
||||||
|
option[0] = toupper(option[0]);
|
||||||
|
if (option == "Y") {
|
||||||
|
cout << "Inner Nodes:" << endl;
|
||||||
|
bst.printInnerNodes(kDisplay);
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildBST(const string &filename, BinarySearchTree<Park> &bst) {
|
||||||
|
ifstream inputFile(filename);
|
||||||
|
cout << "Reading data from \"" << filename << "\"" << endl;
|
||||||
|
|
||||||
|
if (!inputFile) {
|
||||||
|
cout << "Error opening the input file: \"" << filename << "\"" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
string line;
|
||||||
|
while (getline(inputFile, line)) {
|
||||||
|
int year;
|
||||||
|
string code, name, state, dsc;
|
||||||
|
|
||||||
|
stringstream temp(line); // create temp with data from line
|
||||||
|
temp >> code; // read from temp
|
||||||
|
temp >> state;
|
||||||
|
temp >> year;
|
||||||
|
temp.ignore(); // to ignore space in front of name
|
||||||
|
getline(temp, name, ';'); // stop reading name at ';'
|
||||||
|
temp.ignore(); // to ignore space in front of description
|
||||||
|
getline(temp, dsc);
|
||||||
|
// create a Park object and initialize it with data from file
|
||||||
|
Park aPark(code, state, name, dsc, year);
|
||||||
|
bst.insert(aPark);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchManager(const BinarySearchTree<Park> &bst) {
|
||||||
|
string targetCode = "";
|
||||||
|
Park aPark;
|
||||||
|
|
||||||
|
cout << endl << " Search" << endl;
|
||||||
|
cout << "=======" << endl;
|
||||||
|
|
||||||
|
while (targetCode != "Q") {
|
||||||
|
cout << "Enter a park code (or Q to stop searching):" << endl;
|
||||||
|
getline(cin, targetCode);
|
||||||
|
// Convert targetCode to uppercase
|
||||||
|
for (char &c : targetCode) c = toupper(c);
|
||||||
|
if (targetCode != "Q") {
|
||||||
|
Park target;
|
||||||
|
target.setCode(targetCode);
|
||||||
|
if (bst.search(target, aPark))
|
||||||
|
vDisplay(aPark);
|
||||||
|
else
|
||||||
|
cout << "Park \"" << targetCode << "\" was not found in this list." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << "___________________END SEARCH SECTION _____" << endl;
|
||||||
|
}
|
||||||
20
05-trees/national_parks.txt
Normal file
20
05-trees/national_parks.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
MOJ CA 1994 Mojave National Preserve; Spectacular Landscape in Absolute Solitude
|
||||||
|
YOS CA 1890 Yosemite National Park; A Land of Giants
|
||||||
|
LAS CA 1916 Lassen Volcanic National Park; Bubbling Below the Surface
|
||||||
|
PRE CA 1962 Point Reyes National Seashore; Sky Above, Sea Beyond
|
||||||
|
BRC UT 1928 Bryce Canyon National Park; Pillars of Stone
|
||||||
|
DEV CA 1911 Devils Postpile National Monument; A Geologic Gem
|
||||||
|
MUW CA 1908 Muir Woods National Monument; John Muir’s Cathedral
|
||||||
|
CAL UT 1964 Canyonlands National Park; The Heart of the High Desert
|
||||||
|
GLA MT 1910 Glacier National Park; Reflections of the Past
|
||||||
|
ALC CA 1934 Alcatraz Island; Landmark Unlocked
|
||||||
|
YEL WY 1872 Yellowstone National Park; Otherworldly on Earth
|
||||||
|
ROC CO 1915 Rocky Mountain National Park; On Top of the World
|
||||||
|
CRA OR 1902 Crater Lake National Park; Deep and Pristine Waters
|
||||||
|
PIN CA 2013 Pinnacles National Park; Spectacular Remains of an Ancient Volcano
|
||||||
|
DEN AK 1980 Denali National Park and Preserve; Beyond the Mountain
|
||||||
|
ZIO UT 1919 Zion National Park; An Oasis Amidst the Desert
|
||||||
|
JOS CA 1994 Joshua Tree National Park; The Outer Limits of Reality
|
||||||
|
GRC AZ 1908 Grand Canyon National Park; A Sight Beyond Words
|
||||||
|
ARC UT 1929 Arches National Park; Windows to the Sky
|
||||||
|
DEA CA 1994 Death Valley National Park; A Land of Extremes
|
||||||
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