Compare commits

..

13 Commits

Author SHA1 Message Date
4dbe12e593 10.10 Lab*: Heap ADT
Refactor Customer.h slightly
2024-06-08 14:37:32 -07:00
701d84242d 10.10 Lab*: Heap ADT
Now that you have a working implementation of the Heap class, you will convert it to a template.

In this assignment we will create and process a heap of Customer objects. You are encouraged to reuse as much code as possible from previous assignments/labs.

The assignment consists of the following classes/files:

- Customer.cpp (incomplete)
- Customer.h (incomplete)
- Heap.h (template, incomplete)
- main.cpp (incomplete)

Project: An airline company uses the formula shown below to determine the priority of the passengers on the waiting list for overbooked flights.

Priority number = A / 1000 + B – C

Where

- A is the customer’s total mileage in the past year
- B is the customer’s number of years in the flier program
- C is the sequence number representing the customer’s arrival position when the flight was booked (the first customer’s sequence number is 1, second in the file is 2, and so on).

Two or more customers could have the same priority number. For instance, Robert Hill and Tom Martin have the same priority number:

Robert Hill’s priority number: 53000 / 1000 + 5 – 1 = 57
Tom Martin’s priority number: 56000/1000 + 5 – 4 = 57

Customers with the same priority number must be served on a first come first serve basis, therefore build the heap based on a unique serial number determined using the following formula:

serial number = priority * 100 + (100 – C)

In the above example:

Robert Hill’s serial number is: 57 * 100 + (100 – 1) = 5799
Tom Martin’s serial number is: 57 * 100 + (100 – 4) = 5796

Given a file with overbooked customers, write a program that reads the file and determines each customer’s priority number, serial number, and prints a list of waiting customers in priority sequence, including the total number of customers served/rejected. There are two types of lines in the input file: line that begins with 'A' or 'S':

- the letter 'A' represents the arrival of a new customer and it is followed by:
- the number of years in the frequent flier program,
- total mileage in the past year, and the
- name of the customer (see below).

A 5 53000 Robert Hill      // insert into the heap
A 3 89000 Amanda Trapp     // insert into the heap
A 3 90000 Jonathan Nguyen  // insert into the heap
S                          // delete from the heap and print
A 5 56000 Tom Martin       // insert into the heap

The letter 'S' stands for "Serve" and indicates that the next customer from the waiting list will be served (in priority sequence).

Finally, display the overbooked customers that did not get a plain ticket. For each overbooked customer display the number of years in the frequent flier program, total mileage in the past year, the serial number within (), and the name of the customer within [], as shown in the following example.

Example:

Input file name:
3 89000 (9098) [Amanda Trapp]
Served overbooked customers: 1

3 90000 (9097) [Jonathan Nguyen]
5 53000 (5799) [Robert Hill]
5 56000 (5796) [Tom Martin]
Rejected overbooked customers: 3
2024-05-29 22:16:05 -07:00
0789614ef1 10.9 Lab: Heap - Build min/max-heaps (of integers)
Generalize one of the previous labs to build a min-heap or a max-heap using the same heap functions. In main() pass either compareMin or compareMax to the insertHeap function:

- minHeap.insertHeap(num, compareMin);
- maxHeap.insertHeap(num, compareMax);

You also have to update the following functions of the Heap class:

- bool insertHeap(int itemIn);
- bool deleteHeap(int &itemOut);
- void _reHeapUp(int lastndx);
- void _reHeapDown(int rootndx);

This program will:

- read integers from the keyboard and insert them into a min-heap and a max-heap
- display the integers as they are deleted from the min-heap.
- display the integers as they are deleted from the max-heap.
2024-05-28 19:21:43 -07:00
cc06e5fbdb 10.8 Lab: Heap - Display Heap as an Indented List
Change the previous lab to display a min-heap as an indented list (level numbers included). In order to do this you will have to add two new member functions to the heap class

- void _printIndented(int index, void visit(int, int)); // A
- void printIndented(void visit(int, int)); // B

Note: One function would be sufficient(A). However, to make the call simpler, a wrapper function (B) has been added (to "hide" the root of the heap).

Another solution is to add level as a parameter to _printIndented:

- void _printIndented(int index, int level, void visit(int, int));
2024-05-28 18:59:23 -07:00
eb1cf4176f 10.7 Lab: Heap - Build a min-heap (of integers)
Change the previous lab to work with a min-heap instead of a max-heap.
2024-05-28 18:41:58 -07:00
0ca7ce28fd 10.6 Lab: Heap - Build a max-heap (of integers)
This program will read integers from the keyboard, insert them into a max-heap, and display them as they are deleted from the heap. Most of the code is given:

- Heap.h
- Heap.cpp
- main.cpp

Your task is to finish defining four function in Heap.cpp:

- insertHeap
- deleteHeap
- _reHeapUp
- _reHeapDown
2024-05-28 18:33:44 -07:00
276575ca62 6.21 Lab: Doubly-Linked List (Insert - reject duplicates)
Fix memory leak when attempting to insert a duplicate
2024-05-19 13:46:15 -07:00
30ad8892de 9.14 Lab: Hash ADT
Now that you have a working implementation of the HashNode and HashTable classes, you can convert them to templates, and update main.cpp to match with the new template classes.

In order for everything to work you will also have to:

- overload the == operator for the Student class
- declare the hash function a friend function of the Student class
- send the hash function as an argument to insert, remove, and search functions.
2024-05-11 16:44:34 -07:00
b43f08aacc 9.13 Lab: Hashing - Linear Probe (insert, search, delete)
Reuse code from the previous lab and write new code as described below:

- search hash: Modify this function to return -1 if the target key is not found or the number of collisions for that key if found.

`int search(Student &target, string key);`

- remove hash: Create a new function to delete an item from the hash table.
- insert manager: inserts user provided data into the hash table and rejects duplicates.
2024-05-11 16:16:27 -07:00
3d112946f5 9.12 Lab: Hashing - Linear Probe (insert, search)
Hash Function: Add the ASCII values of all characters in the key string and return the reminder obtained when divided by the size of the table.

Example: If key = "Bob", and size = 53, we get (66 + 111 + 98) % 53 => 275 % 53 => 10.

Collision Resolution Method: Linear Probe.

The assignment consists of the following classes/files:

- main.cpp (incomplete)
- Student.h (given)
- HashNode.h (given)
- HashTable.h (given)
- HashTable.cpp (incomplete)

Read and understand the given code then write two functions:

- insert hash
- search hash
2024-05-11 15:43:39 -07:00
01d2d7f2cf 8.14 Lab*: BT <--- BST ADT (Park)
- Modify the Park class from previous assignments.
- Rewrite the private insert as a recursive function.
- Write the buildBST() function (similar to buildList() in the doubly-linked list lab).
- Display the number of nodes in the tree as shown below:

- Display the tree in inorder, preorder or postorder
- Display the tree as an indented list
- Display the inner nodes of the BST (including its root), in alphabetical order by code

- Write the searchManager() function (similar to searchManager() in the doubly-linked list lab). It calls search BST in a loop.
- Search the BST (implement the recursive private search function).
2024-05-03 17:08:04 -07:00
42ba63e654 8.12 Lab: BT <--- BST (Search)
Implement the pair of search functions for searching the BST:

- _search - recursive (private function)
- search - wrapper for _search (public function)
2024-05-03 15:11:07 -07:00
0bc2b9690f 8.9 Lab: BT <--- BST (Indented Tree)
Write a variation of one of the Depth-First Traversal Functions named printTree that displays the indented tree, including the level numbers.
2024-05-03 14:00:39 -07:00
45 changed files with 1364 additions and 95 deletions

View File

@@ -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
View 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
View File

@@ -0,0 +1 @@
05_trees

2
05-trees/.idea/05-trees.iml generated Normal file
View File

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

View 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
View 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
View 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
View 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>

View File

@@ -14,9 +14,10 @@ public:
bool insert(const ItemType &item); bool insert(const ItemType &item);
// remove a node if found // remove a node if found
//bool remove(const ItemType &item); // bool remove(const ItemType &item);
// find a target node // find a target node
//bool search(const ItemType &target, ItemType &returnedItem) const; bool search(const ItemType &target, ItemType &returnedItem) const;
// find the smallest node // find the smallest node
bool findSmallest(ItemType &returnedItem) const; bool findSmallest(ItemType &returnedItem) const;
@@ -28,35 +29,35 @@ private:
BinaryNode<ItemType> *_insert(BinaryNode<ItemType> *nodePtr, BinaryNode<ItemType> *newNode); BinaryNode<ItemType> *_insert(BinaryNode<ItemType> *nodePtr, BinaryNode<ItemType> *newNode);
// search for target node // search for target node
//BinaryNode<ItemType>* _search(BinaryNode<ItemType>* treePtr, const ItemType &target) const; BinaryNode<ItemType> *_search(BinaryNode<ItemType> *treePtr, const ItemType &target) const;
// find the smallest node // find the smallest node
BinaryNode<ItemType> *_findSmallest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const; BinaryNode<ItemType> *_findSmallest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const;
// find the biggest node // find the largest node
BinaryNode<ItemType> *_findLargest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const; BinaryNode<ItemType> *_findLargest(BinaryNode<ItemType> *nodePtr, ItemType &smallest) const;
// internal remove node: locate and delete target node under nodePtr subtree // internal remove node: locate and delete target node under nodePtr subtree
// BinaryNode<ItemType>* _remove(BinaryNode<ItemType>* nodePtr, const ItemType target, bool &success); // BinaryNode<ItemType>* _remove(BinaryNode<ItemType>* nodePtr, const ItemType target, bool &success);
// delete target node from tree, called by internal remove node // delete target node from tree, called by internal remove node
// BinaryNode<ItemType>* _removeNode(BinaryNode<ItemType>* targetNodePtr); // BinaryNode<ItemType>* _removeNode(BinaryNode<ItemType>* targetNodePtr);
// remove the leftmost node in the left subtree of nodePtr // remove the leftmost node in the left subtree of nodePtr
// BinaryNode<ItemType>* _removeLeftmostNode(BinaryNode<ItemType>* nodePtr, ItemType &successor); // BinaryNode<ItemType>* _removeLeftmostNode(BinaryNode<ItemType>* nodePtr, ItemType &successor);
}; };
///////////////////////// public function definitions /////////////////////////// ///////////////////////// public function definitions ///////////////////////////
// Inserting items within a tree // Wrapper for _insert - Inserting items within a tree
template<class ItemType> template<class ItemType>
bool BinarySearchTree<ItemType>::insert(const ItemType &newEntry) { bool BinarySearchTree<ItemType>::insert(const ItemType &newEntry) {
BinaryNode<ItemType> *newNodePtr = new BinaryNode<ItemType>(newEntry); auto *newNodePtr = new BinaryNode<ItemType>(newEntry);
this->rootPtr = _insert(this->rootPtr, newNodePtr); this->rootPtr = _insert(this->rootPtr, newNodePtr);
this->count++;
return true; return true;
} }
// Finding the smallest, which is the leftmost leaf (wrapper function) // Finding the smallest, which is the leftmost leaf (wrapper function)
template<class ItemType> template<class ItemType>
bool BinarySearchTree<ItemType>::findSmallest(ItemType &returnedItem) const { bool BinarySearchTree<ItemType>::findSmallest(ItemType &returnedItem) const {
@@ -65,7 +66,7 @@ bool BinarySearchTree<ItemType>::findSmallest(ItemType &returnedItem) const {
return temp != nullptr; return temp != nullptr;
} }
// Finding the biggest, which is the rightmost leaf (wrapper function) // Finding the largest, which is the rightmost leaf (wrapper function)
template<class ItemType> template<class ItemType>
bool BinarySearchTree<ItemType>::findLargest(ItemType &returnedItem) const { bool BinarySearchTree<ItemType>::findLargest(ItemType &returnedItem) const {
BinaryNode<ItemType> *temp = nullptr; BinaryNode<ItemType> *temp = nullptr;
@@ -73,33 +74,50 @@ bool BinarySearchTree<ItemType>::findLargest(ItemType &returnedItem) const {
return temp != nullptr; 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 //////////////////////////////////////////// //////////////////////////// private functions ////////////////////////////////////////////
// Implementation of the insert operation - iterative algorithm // Recursive implementation of the insert operation
template<class ItemType> template<class ItemType>
BinaryNode<ItemType> *BinarySearchTree<ItemType>::_insert(BinaryNode<ItemType> *nodePtr, BinaryNode<ItemType> *BinarySearchTree<ItemType>::_insert(BinaryNode<ItemType> *nodePtr,
BinaryNode<ItemType> *newNodePtr) { BinaryNode<ItemType> *newNodePtr) {
BinaryNode<ItemType> *pWalk = nodePtr, *parent = nullptr; // Base case: tree is empty
if (nodePtr == nullptr) return newNodePtr;
if (!nodePtr) // == NULL // Inserting larger item to the right:
{ if (nodePtr->getItem() < newNodePtr->getItem()) {
nodePtr = newNodePtr; // Recurse if right child is not null
return nodePtr; if (nodePtr->getRightPtr() != nullptr)
} else { _insert(nodePtr->getRightPtr(), newNodePtr);
while (pWalk) // != NULL // Otherwise, insert the new node
{ else nodePtr->setRightPtr(newNodePtr);
parent = pWalk; }
if (pWalk->getItem() > newNodePtr->getItem()) // Inserting smaller item to the left:
pWalk = pWalk->getLeftPtr(); else {
else // Recurse if left child is not null
pWalk = pWalk->getRightPtr(); if (nodePtr->getLeftPtr() != nullptr)
} _insert(nodePtr->getLeftPtr(), newNodePtr);
if (parent->getItem() > newNodePtr->getItem()) // Otherwise, insert the new node
parent->setLeftPtr(newNodePtr); else nodePtr->setLeftPtr(newNodePtr);
else
parent->setRightPtr(newNodePtr);
} }
// Return the root node
return nodePtr; return nodePtr;
} }
@@ -124,4 +142,22 @@ BinaryNode<ItemType> *BinarySearchTree<ItemType>::_findLargest(BinaryNode<ItemTy
return _findLargest(nodePtr->getRightPtr(), biggest); return _findLargest(nodePtr->getRightPtr(), biggest);
} }
#endif // 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

View File

@@ -35,30 +35,36 @@ public:
count = 0; count = 0;
} }
void preOrder(void visit(ItemType &)) const { _preorder(visit, rootPtr); } void preOrder(void visit(const ItemType &)) const { _preorder(visit, rootPtr); }
void inOrder(void visit(ItemType &)) const { _inorder(visit, rootPtr); } void inOrder(void visit(const ItemType &)) const { _inorder(visit, rootPtr); }
void postOrder(void visit(ItemType &)) const { _postorder(visit, rootPtr); } void postOrder(void visit(const ItemType &)) const { _postorder(visit, rootPtr); }
// void printTree(void visit(ItemType &, int)) const{_printTree(visit, rootPtr, 1);}
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 // abstract functions to be implemented by derived class
virtual bool insert(const ItemType &newData) = 0; virtual bool insert(const ItemType &newData) = 0;
//virtual bool remove(const ItemType &data) = 0; //virtual bool remove(const ItemType &data) = 0;
//virtual bool search(const ItemType &target, ItemType & returnedItem) const = 0; virtual bool search(const ItemType &target, ItemType &returnedItem) const = 0;
private: private:
// delete all nodes from the tree // delete all nodes from the tree
void destroyTree(BinaryNode<ItemType> *nodePtr); void destroyTree(BinaryNode<ItemType> *nodePtr);
// internal traverse // internal traverse
void _preorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const; void _preorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
void _inorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const; void _inorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
void _postorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const; void _postorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const;
// void _printTree(void visit(ItemType &, int), BinaryNode<ItemType>* nodePtr, int level) 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 // Destroy the entire tree
@@ -75,7 +81,7 @@ void BinaryTree<ItemType>::destroyTree(BinaryNode<ItemType> *nodePtr) {
// Preorder Traversal // Preorder Traversal
template<class ItemType> template<class ItemType>
void BinaryTree<ItemType>::_preorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const { void BinaryTree<ItemType>::_preorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
if (nodePtr == nullptr) return; if (nodePtr == nullptr) return;
ItemType item = nodePtr->getItem(); ItemType item = nodePtr->getItem();
@@ -87,7 +93,7 @@ void BinaryTree<ItemType>::_preorder(void visit(ItemType &), BinaryNode<ItemType
// Inorder Traversal // Inorder Traversal
template<class ItemType> template<class ItemType>
void BinaryTree<ItemType>::_inorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const { void BinaryTree<ItemType>::_inorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
if (nodePtr) // != NULL if (nodePtr) // != NULL
{ {
ItemType item = nodePtr->getItem(); ItemType item = nodePtr->getItem();
@@ -99,7 +105,7 @@ void BinaryTree<ItemType>::_inorder(void visit(ItemType &), BinaryNode<ItemType>
// Postorder Traversal // Postorder Traversal
template<class ItemType> template<class ItemType>
void BinaryTree<ItemType>::_postorder(void visit(ItemType &), BinaryNode<ItemType> *nodePtr) const { void BinaryTree<ItemType>::_postorder(void visit(const ItemType &), BinaryNode<ItemType> *nodePtr) const {
if (nodePtr == nullptr) return; if (nodePtr == nullptr) return;
_postorder(visit, nodePtr->getLeftPtr()); _postorder(visit, nodePtr->getLeftPtr());
@@ -108,4 +114,26 @@ void BinaryTree<ItemType>::_postorder(void visit(ItemType &), BinaryNode<ItemTyp
visit(item); 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 #endif

View File

@@ -6,4 +6,6 @@ set(CMAKE_CXX_STANDARD 20)
add_executable(05_trees main.cpp add_executable(05_trees main.cpp
BinaryTree.h BinaryTree.h
BinaryNode.h BinaryNode.h
BinarySearchTree.h) BinarySearchTree.h
Park.cpp
Park.h)

80
05-trees/Park.cpp Normal file
View 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
View 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

View File

@@ -1,74 +1,152 @@
// BST ADT // BST ADT
// Smallest/Largest // Created by Iurii Tatishchev
// Name: Iurii Tatishchev // Modified by: Iurii Tatishchev
#include "BinarySearchTree.h" #include "BinarySearchTree.h"
#include "Park.h"
#include <iostream> #include <iostream>
#include <iomanip>
#include <fstream>
#include <string> #include <string>
#include <cctype>
using namespace std; using namespace std;
void buildBST(int n, BinarySearchTree<int> &); void displayManager(const BinarySearchTree<Park> &bst);
void hDisplay(int &); void buildBST(const string &filename, BinarySearchTree<Park> &bst);
void vDisplay(int &);
void searchManager(const BinarySearchTree<Park> &bst);
int main() { int main() {
BinarySearchTree<int> bst; string filename;
BinarySearchTree<Park> bst;
int n; cout << "What is the input file's name? ";
char option; getline(cin, filename);
buildBST(filename, bst);
cout << "What is the number of nodes in the BST? " << endl; displayManager(bst);
cin >> n; searchManager(bst);
cout << "Find Smallest or Largest[S/L]? " << endl;
cin >> option;
buildBST(n, bst);
if (n < 15) {
cout << " Inorder: ";
bst.inOrder(hDisplay);
cout << endl;
}
if (option == 'S' || option == 's') {
int minVal;
bst.findSmallest(minVal);
cout << "Smallest: " << minVal << endl;
} else if (option == 'L' || option == 'l') {
int maxVal;
bst.findLargest(maxVal);
cout << "Largest: " << maxVal << endl;
}
return 0; return 0;
} }
/* /*
buildBST: builds a binary search tree Display manager: traversals, count, indented tree, and inner nodes
of integers Input Parameter: bst
*/ */
void buildBST(int n, BinarySearchTree<int> &bst) { void displayManager(const BinarySearchTree<Park> &bst) {
int item;
while (n--) { string option;
item = rand() % 30 + 10;
bst.insert(item); // 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) {
horizontal display: all items on one line ifstream inputFile(filename);
*/ cout << "Reading data from \"" << filename << "\"" << endl;
void hDisplay(int &item) {
cout << item << " "; 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) {
vertical display: one item per line string targetCode = "";
*/ Park aPark;
void vDisplay(int &item) {
cout << item << endl; 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;
} }

View 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 Muirs 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
View 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
View File

@@ -0,0 +1 @@
06_hash_tables

2
06-hash-tables/.idea/06-hash-tables.iml generated Normal file
View File

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

View 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
View 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
View 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
View 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>

View 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
View 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

View 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
View 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_

View 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
View 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
View 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
View 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
View File

@@ -0,0 +1 @@
07_heaps

2
07-heaps/.idea/07-heaps.iml generated Normal file
View File

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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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