#include <iostream>
#include <string>
#include <cassert>
using namespace std;
// Define pqEntry class
template <class Item>
class pqEntry {
public:
pqEntry(int p = 0, Item data = Item()) { priority = p; this->data = data; }
friend bool operator <= (const pqEntry<Item>& a, const pqEntry<Item>& b) { return a.priority <= b.priority; }
friend bool operator < (const pqEntry<Item>& a, const pqEntry<Item>& b) { return a.priority < b.priority; }
friend bool operator > (const pqEntry<Item>& a, const pqEntry<Item>& b) { return a.priority > b.priority; }
friend bool operator >= (const pqEntry<Item>& a, const pqEntry<Item>& b) { return a.priority >= b.priority; }
Item getData() const { return data; }
int getPriority() const { return priority; }
private:
Item data;
int priority;
};
// Define Heap class
template <class Item>
class Heap {
public:
typedef Item value_type;
typedef size_t size_type;
static const size_type CAPACITY = 100;
Heap() { used = 0; }
void insert(const Item& entry);
void remove();
Item top() const;
bool empty() const { return used == 0; }
private:
Item data[CAPACITY];
size_type used;
void reheap_down(size_type i);
void reheap_up(size_type i);
};
// Implement Heap methods
template<class Item>
void Heap<Item>::insert(const Item& entry) {
assert(used < CAPACITY);
data[used] = entry;
used++;
reheap_up(used - 1);
}
template<class Item>
void Heap<Item>::remove() {
assert(!empty());
data[0] = data[used - 1];
used--;
reheap_down(0);
}
template<class Item>
Item Heap<Item>::top() const {
assert(!empty());
return data[0];
}
template<class Item>
void Heap<Item>::reheap_down(size_type i) {
Item temp;
if ((data[2 * i + 1] > data[2 * i + 2] && data[2 * i + 1] > data[i]) && (2 * i + 1 < used)) {
temp = data[2 * i + 1];
data[2 * i + 1] = data[i];
data[i] = temp;
reheap_down(2 * i + 1);
} else if ((data[2 * i + 1] <= data[2 * i + 2] && data[2 * i + 2] > data[i]) && (2 * i + 2 < used)) {
temp = data[2 * i + 2];
data[2 * i + 2] = data[i];
data[i] = temp;
reheap_down(2 * i + 2);
}
}
template<class Item>
void Heap<Item>::reheap_up(size_type i) {
Item temp;
if (i != 0 && (data[(i - 1) / 2] < data[i])) {
temp = data[i];
data[i] = data[(i - 1) / 2];
data[(i - 1) / 2] = temp;
reheap_up((i - 1) / 2);
}
}
// Define PQueue class
template <class Item>
class PQueue {
public:
void pop();
void push(const pqEntry<Item>& entry);
Item front();
bool empty();
size_t size();
private:
Heap<pqEntry<Item>> storage;
};
// Implement PQueue methods
template <class Item>
void PQueue<Item>::pop() {
storage.remove();
}
template <class Item>
void PQueue<Item>::push(const pqEntry<Item>& entry) {
storage.insert(entry);
}
template <class Item>
Item PQueue<Item>::front() {
return storage.top().getData();
}
template <class Item>
bool PQueue<Item>::empty() {
return storage.empty();
}
template <class Item>
size_t PQueue<Item>::size() {
return storage.size();
}
// Main program
int main() {
PQueue<string> pq;
// Push tasks with priorities into the priority queue
pq.push(pqEntry<string>(7, "Take out trash"));
pq.push(pqEntry<string>(9, "Do HW"));
pq.push(pqEntry<string>(10, "Get groceries"));
pq.push(pqEntry<string>(8, "Make dinner"));
pq.push(pqEntry<string>(4, "Watch TV"));
// Display the tasks in priority order
cout << "Priority Queue (tasks with highest priority first):" << endl;
while (!pq.empty()) {
cout << pq.front() << endl;
pq.pop();
}
return 0;
}