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
Changed by: Iurii Tatishchev
IDE: CLion
@ -12,25 +12,27 @@ IDE: CLion
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) {
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 (child not less than parent)
if (heapAry[lastndx] >= heapAry[parentIndex]) return;
// 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);
_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) {
void Heap::_reHeapDown(int rootdex, int (compareFunc)(int, int)) {
int maxChildIndex = -1;
int left = _findLeftChild(rootdex);
@ -38,30 +40,32 @@ void Heap::_reHeapDown(int rootdex) {
// if there is a left child
if (left != -1) {
// if there is a right child that is less than the left child
if (right != -1 && heapAry[right] < heapAry[left]) maxChildIndex = right;
// 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 (children greater than parent)
if (maxChildIndex == -1 || heapAry[rootdex] < heapAry[maxChildIndex]) return;
// 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);
_reHeapDown(maxChildIndex, compareFunc);
}
/* *~*~*
The public member function insertHeap inserts a new item into a heap.
It calls _reheapUp.
*~**/
bool Heap::insertHeap(int newItem) {
if (isFull()) {
return false;
}
bool Heap::insertHeap(int newItem, int (compareFunc)(int, int)) {
if (isFull()) return false;
heapAry[count] = newItem;
_reHeapUp(count);
_reHeapUp(count, compareFunc);
count++;
return true;
@ -71,24 +75,13 @@ bool Heap::insertHeap(int newItem) {
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) {
if (isEmpty()) {
return false;
}
bool Heap::deleteHeap(int &returnItem, int (compareFunc)(int, int)) {
if (isEmpty()) return false;
returnItem = heapAry[0];
heapAry[0] = heapAry[count - 1];
count--;
_reHeapDown(0);
_reHeapDown(0, compareFunc);
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
Changed by: Iurii Tatishchev
IDE: CLion
*~**/
@ -13,9 +14,9 @@ private:
int heapSize;
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; }
@ -46,14 +47,10 @@ public:
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

View File

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