A heap is the best choice of data structure when we need quick access to the largest or smallest value in a queue. Some applications are:
Discuss in small groups:
ER is empty
4 patients waiting.
Next patient to be seen: Patient severity: 5, arrival time: 09:41:30.597749
Seeing patients:
Patient severity: 5, arrival time: 09:41:30.597749
Patient severity: 4, arrival time: 09:41:30.588172
Patient severity: 2, arrival time: 09:41:30.597763
Patient severity: 1, arrival time: 09:41:30.597723
public class RunER {
public static void main(String[] args) {
Triage er = new Triage();
System.out.println(er);
er.insert(new Patient(4));
er.insert(new Patient(1));
er.insert(new Patient(5));
er.insert(new Patient(2));
System.out.println(er);
System.out.println("Seeing patients: ");
while (!er.isEmpty()) {
System.out.println(er.seePatient());
}
}
}import java.time.LocalTime;
import java.time.Duration;
public class Patient implements Comparable<Patient> {
private int severity;
private LocalTime arrivalTime;
public Patient(int severity) {
if (!validSeverity(severity)) throw new RuntimeException("severity must be 1-5");
this.severity = severity;
arrivalTime = LocalTime.now();
}
private boolean validSeverity(int severity) {
return severity >= 1 && severity <= 5;
}
public int getSeverity() { return severity; }
public boolean setSeverity(int severity) {
if (!validSeverity(severity)) return false;
this.severity = severity;
return true;
}
public LocalTime getArrivalTime() { return arrivalTime; }
public double getWaitTimeMinutes() {
Duration wait = Duration.between(arrivalTime,LocalTime.now());
return wait.toMinutes();
}
public int compareTo(Patient other) {
if (other == null) return 1;
if (this == other) return 0;
return this.severity - other.severity;
}
public String toString() {
String out = "Patient severity: " + severity;
out += ", arrival time: " + arrivalTime;
return out;
}
}public class Triage {
private Patient[] patients;
private int patientCount = 0;
private int erCapacity = 100;
public Triage() {
patients = new Patient[erCapacity];
}
public int getPatientCount() {
return patientCount;
}
private int parent(int i) { return (i - 1) / 2; }
private int leftChild(int i) { return 2 * i + 1; }
private int rightChild(int i){ return 2 * i + 2; }
private boolean hasParent(int i) { return i > 0; }
private boolean hasLeftChild(int i) { return leftChild(i) < patientCount; }
private boolean hasRightChild(int i) { return rightChild(i) < patientCount; }
public boolean isEmpty() { return patientCount == 0; }
// Returns the minimum element (root) without removing it — O(1)
public Patient nextPatientInfo() {
if (isEmpty()) throw new IllegalStateException("ER is empty");
return patients[0];
}
// Inserts a new value and restores the heap property — O(log n)
public void insert(Patient value) {
if (patientCount == erCapacity) throw new IllegalStateException("ER is full");
patients[patientCount] = value; // place at the next open spot
patientCount++;
bubbleUp(patientCount - 1); // restore heap property upward
}
// Removes and returns the minimum element — O(log n)
public Patient seePatient() {
if (isEmpty()) throw new IllegalStateException("ER is empty");
Patient min = patients[0];
patients[0] = patients[patientCount - 1];
patientCount--;
bubbleDown(0);
return min;
}
private void swap(int a, int b) {
Patient temp = patients[a];
patients[a] = patients[b];
patients[b] = temp;
}
private void bubbleUp(int i) {
while (hasParent(i) && patients[i].compareTo(patients[parent(i)]) > 0) {
swap(i, parent(i));
i = parent(i);
}
}
// used after pop min
private void bubbleDown(int i) {
while (hasLeftChild(i)) {
int largerChild = leftChild(i);
// find the smaller of the two children
if (hasRightChild(i) && patients[rightChild(i)].compareTo(patients[leftChild(i)]) > 0) {
largerChild = rightChild(i);
}
if (patients[i].compareTo(patients[largerChild]) >= 0) return;
swap(i, largerChild);
i = largerChild;
}
}
public String toString() {
if (isEmpty()) return "ER is empty";
String out = "Patient list:\n";
for (int i = 0; i < patientCount; i++) out += patients[i] + "\n";
out += "\nNext patient to be seen: " + nextPatientInfo().toString();
return out.trim();
}
}