#pragma once #include "LinkedList.h" /* File Name: PriorityQueue.h Author: Essam Fahmy Date: 2023-11-01 PriorityQueue declarations and implementations */ #include "Patient.h" #include <stdexcept> template <typename T> class PriorityQueue { LinkedList<T> patients_; bool isDuplicate(const T& patient) { typename LinkedList<T>::Node* current = patients_.begin(); while (current != nullptr) { if (current->data == patient) { return true; } current = current->next; } return false; } public: PriorityQueue() {} bool empty() const { return patients_.empty(); } size_t size() const { return patients_.size(); } void enqueue(const T& patient) { if (isDuplicate(patient)) { throw std::invalid_argument("Duplicate patient"); } // If the list is empty or the new patient has a higher score than the first patient if (empty() || patient.get_score() > patients_.begin()->data.get_score()) { patients_.push_front(patient); } else { typename LinkedList<T>::Node* current = patients_.begin(); // Traverse the list until the right position is found while (current->next != nullptr && current->next->data.get_score() >= patient.get_score()) { current = current->next; } // Insert the new patient typename LinkedList<T>::Node* newNode = new typename LinkedList<T>::Node(); newNode->data = patient; newNode->next = current->next; newNode->previous = current; if (current->next != nullptr) { current->next->previous = newNode; } else { // If we're at the end, update the end pointer patients_.push_back(patient); delete newNode; return; } current->next = newNode; } } typename LinkedList<T>::Node* begin() { return patients_.begin(); } typename LinkedList<T>::Node* end() { return nullptr; } T dequeue() { if (empty()) { throw std::out_of_range("Queue is empty"); } return patients_.pop_front(); } };