-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPriorityQueueDemo.java
More file actions
143 lines (128 loc) · 5.38 KB
/
Copy pathPriorityQueueDemo.java
File metadata and controls
143 lines (128 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package Phase5_CollectionsLambdasStreams.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
/**
* java.util.PriorityQueue<E> - Heap-Backed Priority Queue
* --------------------------------------------------------
* A PriorityQueue is a Queue where elements come out in PRIORITY order, not
* the order they were added. Internally it uses a BINARY HEAP stored in an
* array, so the "top" element (smallest by natural order, by default) is
* always at index 0.
* <p>
*
* Why It Exists
* -------------
* Many real-world scheduling problems need "give me the most important
* thing next" - earliest deadline first, shortest path next, highest
* priority task next, top-K elements. A PriorityQueue does that in
* O(log n) per add/remove.
* <p>
*
* When To Use It
* --------------
* - Dijkstra / A* (shortest path).
* - Task schedulers ranked by priority or deadline.
* - Top-K problems (keep the K smallest / largest seen so far).
* - Event simulators that fire events in time order.
* <p>
*
* Big-O
* -----
* offer / add / poll / remove (head) O(log n)
* peek / element O(1)
* contains O(n)
* remove(Object o) (not head) O(n)
* <p>
*
* Ordering
* --------
* By default a PriorityQueue is a MIN-HEAP using natural ordering. You
* change the order by supplying a Comparator in the constructor.
* <p>
*
* new PriorityQueue<>() // min-heap
* new PriorityQueue<>(Comparator.reverseOrder()) // max-heap
* new PriorityQueue<>(Comparator.comparing(Task::deadline))
* <p>
*
* Iteration is NOT Ordered
* ------------------------
* The Iterator and toString walk the underlying array, NOT in priority
* order. To see elements in order, repeatedly poll().
* <p>
*
* Constructors
* ------------
* new PriorityQueue<>()
* new PriorityQueue<>(int initialCapacity)
* new PriorityQueue<>(Comparator<? super E>)
* new PriorityQueue<>(int initialCapacity, Comparator<? super E>)
* new PriorityQueue<>(Collection<? extends E>)
*/
public class PriorityQueueDemo {
record Task(String name, int priority, long deadlineMs) {}
public static void main(String[] args) {
section("1) Min-heap by natural order (the default)");
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int n : new int[]{5, 1, 4, 2, 3}) pq.offer(n);
System.out.println("internal array (toString): " + pq);
System.out.print("drained in order: ");
while (!pq.isEmpty()) System.out.print(pq.poll() + " ");
System.out.println();
section("2) Max-heap via Comparator.reverseOrder()");
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
for (int n : new int[]{5, 1, 4, 2, 3}) maxHeap.offer(n);
System.out.print("drained largest first: ");
while (!maxHeap.isEmpty()) System.out.print(maxHeap.poll() + " ");
System.out.println();
section("3) Custom Comparator on a record");
PriorityQueue<Task> byPriority = new PriorityQueue<>(
Comparator.comparingInt(Task::priority)
);
byPriority.offer(new Task("Pay rent", 3, 1));
byPriority.offer(new Task("Fix prod bug", 1, 2));
byPriority.offer(new Task("Send invoice", 2, 3));
byPriority.offer(new Task("Buy milk", 5, 4));
while (!byPriority.isEmpty()) {
System.out.println(" next -> " + byPriority.poll());
}
section("4) Top-K via a bounded min-heap (classic interview trick)");
// Keep the K LARGEST seen so far using a MIN-heap of size K.
// The smallest of the K is always at the top - cheap to evict.
int[] stream = {7, 1, 9, 3, 6, 4, 8, 2, 5};
int k = 3;
PriorityQueue<Integer> topK = new PriorityQueue<>(k); // min-heap
for (int n : stream) {
if (topK.size() < k) topK.offer(n);
else if (n > topK.peek()) {
topK.poll();
topK.offer(n);
}
}
// Drain to read top-K in ascending order
while (!topK.isEmpty()) System.out.print(topK.poll() + " ");
System.out.println("(top-" + k + " of stream)");
section("5) Beware - iteration is NOT priority order");
PriorityQueue<Integer> p = new PriorityQueue<>(List.of(7, 1, 5, 3, 9));
System.out.print("iterator says: ");
for (int n : p) System.out.print(n + " ");
System.out.println();
System.out.print("polling says : ");
while (!p.isEmpty()) System.out.print(p.poll() + " ");
System.out.println();
section("6) remove(Object) - O(n), but valid");
PriorityQueue<Integer> q = new PriorityQueue<>(List.of(7, 1, 5, 3, 9));
q.remove(5);
System.out.println("after remove(5): " + q);
section("7) Constructor from Collection - heapified in O(n)");
PriorityQueue<Integer> bulk = new PriorityQueue<>(List.of(9, 3, 7, 1, 5, 8, 2, 4, 6));
System.out.print("drained: ");
while (!bulk.isEmpty()) System.out.print(bulk.poll() + " ");
System.out.println();
// OUTPUT (representative)
}
private static void section(String title) {
System.out.println("\n====== " + title + " ======");
}
}