-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPriorityQueue.java
125 lines (98 loc) · 2.92 KB
/
PriorityQueue.java
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
import java.util.Comparator;
import java.util.NoSuchElementException;
@SuppressWarnings("unchecked")
public class PriorityQueue<Key> {
private Key[] pq;
private int N;
private Comparator<Key> comparator;
public PriorityQueue(int initCapacity) {
pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
public PriorityQueue() { this(1); }
public PriorityQueue(int initCapacity, Comparator<Key> comparator) {
this.comparator = comparator;
pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
public PriorityQueue(Comparator<Key> comparator) { this(1, comparator); }
public PriorityQueue(Key[] keys) {
N = keys.length;
pq = (Key[]) new Object[keys.length + 1];
for (int i = 0; i < N; i++)
pq[i+1] = keys[i];
for (int k = N/2; k >= 1; k--)
sink(k);
assert isMinHeap();
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public Key min() {
if (isEmpty()) throw new NoSuchElementException("Priority queue underflow");
return pq[1];
}
private void resize(int capacity) {
assert capacity > N;
Key[] temp = (Key[]) new Object[capacity];
for (int i = 1; i <= N; i++) temp[i] = pq[i];
pq = temp;
}
public void insert(Key x) {
if (N == pq.length - 1) resize(2 * pq.length);
pq[++N] = x;
swim(N);
assert isMinHeap();
}
public Key delMin() {
if (isEmpty()) throw new NoSuchElementException("Priority queue underflow");
swap(1, N);
Key min = pq[N--];
sink(1);
pq[N+1] = null;
if ((N > 0) && (N == (pq.length - 1) / 4)) resize(pq.length / 2);
assert isMinHeap();
return min;
}
private void swim(int k) {
while (k > 1 && greater(k/2, k)) {
swap(k, k/2);
k = k/2;
}
}
private void sink(int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && greater(j, j+1)) j++;
if (!greater(k, j)) break;
swap(k, j);
k = j;
}
}
private boolean greater(int i, int j) {
if (comparator == null) {
return ((Comparable<Key>) pq[i]).compareTo(pq[j]) > 0;
}
else {
return comparator.compare(pq[i], pq[j]) > 0;
}
}
private void swap(int i, int j) {
Key swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
}
private boolean isMinHeap() {
return isMinHeap(1);
}
private boolean isMinHeap(int k) {
if (k > N) return true;
int left = 2*k, right = 2*k + 1;
if (left <= N && greater(k, left)) return false;
if (right <= N && greater(k, right)) return false;
return isMinHeap(left) && isMinHeap(right);
}
}