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.
This commit is contained in:
Iurii Tatishchev 2024-05-28 19:21:43 -07:00
parent cc06e5fbdb
commit 0789614ef1
Signed by: CaZzzer
GPG Key ID: 9A156B7DA6398968
3 changed files with 72 additions and 61 deletions

View File

@ -1,5 +1,5 @@
/* *~*~* /* *~*~*
Implementation file for the Heap class: max-heap of integers Implementation file for the Heap class: min- or max-heap of integers
Written By: Iurii Tatishchev Written By: Iurii Tatishchev
Changed by: Iurii Tatishchev Changed by: Iurii Tatishchev
IDE: CLion IDE: CLion
@ -12,25 +12,27 @@ IDE: CLion
The private member function _reHeapUp rearranges the heap after insert by moving the The private member function _reHeapUp rearranges the heap after insert by moving the
last item up to the correct location in the heap last item up to the correct location in the heap
*~**/ *~**/
void Heap::_reHeapUp(int lastndx) { void Heap::_reHeapUp(int lastndx, int (compareFunc)(int, int)) {
// base case, newElement is heap's root // base case, newElement is heap's root
if (lastndx == 0) return; if (lastndx == 0) return;
int parentIndex = _findParent(lastndx); int parentIndex = _findParent(lastndx);
// base case, newElement satisfies heap property (child not less than parent) // base case, newElement satisfies heap property
if (heapAry[lastndx] >= heapAry[parentIndex]) return; // 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 // swap and continue recursing
std::swap(heapAry[lastndx], heapAry[parentIndex]); std::swap(heapAry[lastndx], heapAry[parentIndex]);
_reHeapUp(parentIndex); _reHeapUp(parentIndex, compareFunc);
} }
/* *~*~* /* *~*~*
The private member function _reHeapDown rearranges the heap after delete by moving the 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 data in the root down to the correct location in the heap
*~**/ *~**/
void Heap::_reHeapDown(int rootdex) { void Heap::_reHeapDown(int rootdex, int (compareFunc)(int, int)) {
int maxChildIndex = -1; int maxChildIndex = -1;
int left = _findLeftChild(rootdex); int left = _findLeftChild(rootdex);
@ -38,30 +40,32 @@ void Heap::_reHeapDown(int rootdex) {
// if there is a left child // if there is a left child
if (left != -1) { if (left != -1) {
// if there is a right child that is less than the left child // if there is a right child that is
if (right != -1 && heapAry[right] < heapAry[left]) maxChildIndex = right; // 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; else maxChildIndex = left;
} }
// base case, heap property satisfied (children greater than parent) // base case, heap property satisfied
if (maxChildIndex == -1 || heapAry[rootdex] < heapAry[maxChildIndex]) return; // 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 // swap and continue recursing
std::swap(heapAry[rootdex], heapAry[maxChildIndex]); std::swap(heapAry[rootdex], heapAry[maxChildIndex]);
_reHeapDown(maxChildIndex); _reHeapDown(maxChildIndex, compareFunc);
} }
/* *~*~* /* *~*~*
The public member function insertHeap inserts a new item into a heap. The public member function insertHeap inserts a new item into a heap.
It calls _reheapUp. It calls _reheapUp.
*~**/ *~**/
bool Heap::insertHeap(int newItem) { bool Heap::insertHeap(int newItem, int (compareFunc)(int, int)) {
if (isFull()) { if (isFull()) return false;
return false;
}
heapAry[count] = newItem; heapAry[count] = newItem;
_reHeapUp(count); _reHeapUp(count, compareFunc);
count++; count++;
return true; return true;
@ -71,24 +75,13 @@ bool Heap::insertHeap(int newItem) {
The public member function deleteHeap deletes the root of the heap and The public member function deleteHeap deletes the root of the heap and
passes back the root's data. It calls _reheapDown. passes back the root's data. It calls _reheapDown.
*~**/ *~**/
bool Heap::deleteHeap(int &returnItem) { bool Heap::deleteHeap(int &returnItem, int (compareFunc)(int, int)) {
if (isEmpty()) { if (isEmpty()) return false;
return false;
}
returnItem = heapAry[0]; returnItem = heapAry[0];
heapAry[0] = heapAry[count - 1]; heapAry[0] = heapAry[count - 1];
count--; count--;
_reHeapDown(0); _reHeapDown(0, compareFunc);
return true; return true;
} }
void Heap::_printIndented(int index, int level, void (*visit)(int item, int level)) {
if (_findRightChild(index) != -1)
_printIndented(_findRightChild(index), level + 1, visit);
visit(heapAry[index], level);
if (_findLeftChild(index) != -1)
_printIndented(_findLeftChild(index), level + 1, visit);
}

View File

@ -1,6 +1,7 @@
/* *~*~* /* *~*~*
Specification file for the Heap class: max-heap of integers Specification file for the Heap class: min- or max-heap of integers
Written By: Iurii Tatishchev Written By: Iurii Tatishchev
Changed by: Iurii Tatishchev
IDE: CLion IDE: CLion
*~**/ *~**/
@ -13,9 +14,9 @@ private:
int heapSize; int heapSize;
int count; int count;
void _reHeapUp(int lastndx); void _reHeapUp(int lastndx, int (compareFunc)(int, int));
void _reHeapDown(int rootndx); void _reHeapDown(int rootndx, int (compareFunc)(int, int));
int _findParent(int index) { return (index <= 0) ? (-1) : (index - 1) / 2; } int _findParent(int index) { return (index <= 0) ? (-1) : (index - 1) / 2; }
@ -46,14 +47,10 @@ public:
bool isFull() const { return count == heapSize; } bool isFull() const { return count == heapSize; }
bool insertHeap(int itemIn); bool insertHeap(int itemIn, int (compareFunc)(int, int));
bool deleteHeap(int &itemOut); bool deleteHeap(int &itemOut, int (compareFunc)(int, int));
// other functions added
void printIndented(void visit(int item, int level)) { _printIndented(0, 0, visit); };
void _printIndented(int index, int level, void visit(int item, int level));
}; };
#endif #endif

View File

@ -1,8 +1,12 @@
/* /*
This program will This program will
- read integers from the keyboard and insert them into a min-heap, - read integers from the keyboard and insert them into a min-heap and a max-heap
- display the min-heap as an indented list (level numbers included) and - display the integers as they are deleted from the min-heap.
- display the integers as they are deleted from the heap. - display the integers as they are deleted from the max-heap.
Written By: Iurii Tatishchev
Changed by: Iurii Tatishchev
IDE: CLion
*/ */
#include <iostream> #include <iostream>
@ -10,29 +14,36 @@
using namespace std; using namespace std;
void iDisplay(int item, int level); int compareMin(int, int);
int compareMax(int, int);
int main() { int main() {
Heap heap; Heap minHeap(32);
Heap maxHeap(32);
// build heap // build min- and max-heaps
int num; int num;
cout << "Enter integers [0 - to stop]" << endl; cout << "Enter integers [0 - to stop]" << endl;
cin >> num; cin >> num;
while (num != 0) { while (num != 0) {
heap.insertHeap(num); minHeap.insertHeap(num, compareMin);
maxHeap.insertHeap(num, compareMax);
cin >> num; cin >> num;
} }
cout << "Heap capacity: " << heap.getSize() << endl;
cout << "Heap actual number of elements: " << heap.getCount() << endl;
heap.printIndented(iDisplay); // 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 << " ";
}
cout << endl;
// print items as they are deleted from the heap (sorted) // print items as they are deleted from the heap (sorted in descending order)
if (heap.isEmpty()) cout << "Max-Heap: ";
cout << "N/A"; while (!maxHeap.isEmpty()) {
while (!heap.isEmpty()) { maxHeap.deleteHeap(num, compareMax);
heap.deleteHeap(num);
cout << num << " "; cout << num << " ";
} }
cout << endl; cout << endl;
@ -40,14 +51,24 @@ int main() {
return 0; 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;
}
/* /*
indented display: compare two data items: needed to build a max-heap
displays one item including the level number
and corresponding indentation
*/ */
void iDisplay(int item, int level) { int compareMax(int x, int y) {
for (int i = 0; i < level; i++) if (x > y)
cout << ".."; return -1;
cout << level << "). " << item << endl; if (x == y)
return 0;
return 1;
} }