diff --git a/07-heaps/CMakeLists.txt b/07-heaps/CMakeLists.txt index 2074bf2..cb8577e 100644 --- a/07-heaps/CMakeLists.txt +++ b/07-heaps/CMakeLists.txt @@ -4,4 +4,4 @@ project(07_heaps) set(CMAKE_CXX_STANDARD 20) add_executable(07_heaps main.cpp - Heap.cpp) +) diff --git a/07-heaps/Customer.cpp b/07-heaps/Customer.cpp new file mode 100644 index 0000000..e61d118 --- /dev/null +++ b/07-heaps/Customer.cpp @@ -0,0 +1,13 @@ +/* *~*~* +Implementation file for the Customer class +Written By: Iurii Tatishchev +Changed by: Iurii Tatishchev +IDE: CLion +*~**/ +#include +#include +#include "Customer.h" + +using namespace std; + +/* Write your code here */ diff --git a/07-heaps/Customer.h b/07-heaps/Customer.h new file mode 100644 index 0000000..b186886 --- /dev/null +++ b/07-heaps/Customer.h @@ -0,0 +1,44 @@ +/* *~*~* + Specification file for the Customer class + Written By: Iurii Tatishchev + Changed by: Iurii Tatishchev + IDE: CLion + *~**/ +#ifndef CUSTOMER_H_ +#define CUSTOMER_H_ + +#include + +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 = mileage / 1000 + year - seq; + serial = priority * 100 + (100 - seq); + }; + + int getPriority() const { return priority; } + + int getSerial() const { return serial; } + + friend ostream &operator<<(ostream &os, const Customer &c) { + os << c.year << " " << c.mileage << " (" << c.getSerial() << ") [" << c.name << "]"; + return os; + } +}; + +#endif diff --git a/07-heaps/Heap.cpp b/07-heaps/Heap.cpp deleted file mode 100644 index 31c687e..0000000 --- a/07-heaps/Heap.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* *~*~* -Implementation file for the Heap class: min- or max-heap of integers -Written By: Iurii Tatishchev -Changed by: Iurii Tatishchev -IDE: CLion -*~**/ - -#include -#include "Heap.h" - -/* *~*~* - The private member function _reHeapUp rearranges the heap after insert by moving the - last item up to the correct location in the heap - *~**/ -void Heap::_reHeapUp(int lastndx, int (compareFunc)(int, int)) { - - // 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 - *~**/ -void Heap::_reHeapDown(int rootdex, int (compareFunc)(int, int)) { - 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. - *~**/ -bool Heap::insertHeap(int newItem, int (compareFunc)(int, int)) { - 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. - *~**/ -bool Heap::deleteHeap(int &returnItem, int (compareFunc)(int, int)) { - if (isEmpty()) return false; - - returnItem = heapAry[0]; - heapAry[0] = heapAry[count - 1]; - count--; - _reHeapDown(0, compareFunc); - - return true; -} diff --git a/07-heaps/Heap.h b/07-heaps/Heap.h index a88cd17..194312a 100644 --- a/07-heaps/Heap.h +++ b/07-heaps/Heap.h @@ -8,15 +8,16 @@ IDE: CLion #ifndef HEAP_H_ #define HEAP_H_ +template class Heap { private: - int *heapAry; + T *heapAry; int heapSize; int count; - void _reHeapUp(int lastndx, int (compareFunc)(int, int)); + void _reHeapUp(int lastndx, int (compareFunc)(const T&, const T&)); - void _reHeapDown(int rootndx, int (compareFunc)(int, int)); + void _reHeapDown(int rootndx, int (compareFunc)(const T&, const T&)); int _findParent(int index) { return (index <= 0) ? (-1) : (index - 1) / 2; } @@ -28,13 +29,13 @@ public: Heap() { count = 0; heapSize = 128; - heapAry = new int[heapSize]; + heapAry = new T[heapSize]; } Heap(int n) { count = 0; heapSize = n; - heapAry = new int[heapSize]; + heapAry = static_cast(new T[heapSize]); } ~Heap() { delete[] heapAry; } @@ -47,10 +48,88 @@ public: bool isFull() const { return count == heapSize; } - bool insertHeap(int itemIn, int (compareFunc)(int, int)); + bool insertHeap(T &itemIn, int (compareFunc)(const T&, const T&)); - bool deleteHeap(int &itemOut, int (compareFunc)(int, int)); + bool deleteHeap(T &itemOut, int (compareFunc)(const T&, const T&)); }; +template +void Heap::_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 +void Heap::_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 +bool Heap::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 +bool Heap::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 diff --git a/07-heaps/main.cpp b/07-heaps/main.cpp index 3b619b3..c1ea5e4 100644 --- a/07-heaps/main.cpp +++ b/07-heaps/main.cpp @@ -1,74 +1,105 @@ /* - 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. + Heaps - ADT - Written By: Iurii Tatishchev - Changed by: Iurii Tatishchev - IDE: CLion + 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 +#include +#include +#include "Customer.h" #include "Heap.h" using namespace std; -int compareMin(int, int); +// Function Prototypes +int compareCustomer(const Customer &c1, const Customer &c2); -int compareMax(int, int); +void processArrival(Heap &heap, ifstream &inputFile, int seq); + +void processServe(Heap &heap); + +void displayRejected(Heap &heap); int main() { - Heap minHeap(32); - Heap maxHeap(32); - - // build min- and max-heaps - int num; - cout << "Enter integers [0 - to stop]" << endl; - cin >> num; - while (num != 0) { - minHeap.insertHeap(num, compareMin); - maxHeap.insertHeap(num, compareMax); - cin >> num; - } - - // print items as they are deleted from the min-heap (sorted in ascending order) - cout << "Min-Heap: "; - while (!minHeap.isEmpty()) { - minHeap.deleteHeap(num, compareMin); - cout << num << " "; - } + // Get input file name + string inputFileName; + cout << "Input file name: "; + getline(cin, inputFileName); cout << endl; - // print items as they are deleted from the heap (sorted in descending order) - cout << "Max-Heap: "; - while (!maxHeap.isEmpty()) { - maxHeap.deleteHeap(num, compareMax); - cout << num << " "; + // Open input file + ifstream inputFile(inputFileName); + if (!inputFile.good()) { + cerr << "Error: could not open file " << inputFileName << "\n"; + return 1; } - cout << endl; + + // Create heap + Heap 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; } -/* - compare two data items: needed to build a min-heap -*/ -int compareMin(int x, int y) { - if (x < y) - return -1; - if (x == y) - return 0; - return 1; +int compareCustomer(const Customer &c1, const Customer &c2) { + if (c1.getSerial() < c2.getSerial()) return 1; + if (c1.getSerial() > c2.getSerial()) return -1; + return 0; } -/* - compare two data items: needed to build a max-heap -*/ -int compareMax(int x, int y) { - if (x > y) - return -1; - if (x == y) - return 0; - return 1; +void processArrival(Heap &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 &heap) { + if (heap.isEmpty()) { + cout << "Heap is empty" << endl; + return; + } + Customer customer; + heap.deleteHeap(customer, compareCustomer); + cout << customer << endl; +} + +void displayRejected(Heap &heap) { + Customer customer; + while (!heap.isEmpty()) { + heap.deleteHeap(customer, compareCustomer); + cout << customer << endl; + } } diff --git a/07-heaps/overbooked.txt b/07-heaps/overbooked.txt new file mode 100644 index 0000000..98ee99c --- /dev/null +++ b/07-heaps/overbooked.txt @@ -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 diff --git a/07-heaps/overbooked_1.txt b/07-heaps/overbooked_1.txt new file mode 100644 index 0000000..f01d221 --- /dev/null +++ b/07-heaps/overbooked_1.txt @@ -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 \ No newline at end of file diff --git a/07-heaps/overbooked_2.txt b/07-heaps/overbooked_2.txt new file mode 100644 index 0000000..7535119 --- /dev/null +++ b/07-heaps/overbooked_2.txt @@ -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 \ No newline at end of file diff --git a/07-heaps/test.txt b/07-heaps/test.txt new file mode 100644 index 0000000..d9e1b56 --- /dev/null +++ b/07-heaps/test.txt @@ -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