source: osm/applications/editors/josm/plugins/utilsplugin2/src/edu/princeton/cs/algs4/IndexMinPQ.java

Last change on this file was 36362, checked in by stoecker, 13 months ago

see #23688, patch for local URL calling

File size: 6.0 KB
Line 
1// License: GPL v3 or later courtesy of author Kevin Wayne
2package edu.princeton.cs.algs4;
3
4/* ************************************************************************
5 * Compilation: javac IndexMinPQ.java
6 * Execution: java IndexMinPQ
7 *
8 * Indexed PQ implementation using a binary heap.
9 *
10 *********************************************************************/
11
12import java.util.Iterator;
13import java.util.NoSuchElementException;
14
15public class IndexMinPQ<Key extends Comparable<Key>> implements Iterable<Integer> {
16 private int N; // number of elements on PQ
17 private int[] pq; // binary heap using 1-based indexing
18 private int[] qp; // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
19 private Key[] keys; // keys[i] = priority of i
20
21 @SuppressWarnings("unchecked")
22 public IndexMinPQ(int NMAX) {
23 keys = (Key[]) new Comparable[NMAX + 1]; // make this of length NMAX??
24 pq = new int[NMAX + 1];
25 qp = new int[NMAX + 1]; // make this of length NMAX??
26 for (int i = 0; i <= NMAX; i++) qp[i] = -1;
27 }
28
29 // is the priority queue empty?
30 public boolean isEmpty() { return N == 0; }
31
32 // is k an index on the priority queue?
33 public boolean contains(int k) {
34 return qp[k] != -1;
35 }
36
37 // number of keys in the priority queue
38 public int size() {
39 return N;
40 }
41
42 // associate key with index k
43 public void insert(int k, Key key) {
44 if (contains(k)) throw new NoSuchElementException("item is already in pq");
45 N++;
46 qp[k] = N;
47 pq[N] = k;
48 keys[k] = key;
49 swim(N);
50 }
51
52 // return the index associated with a minimal key
53 public int minIndex() {
54 if (N == 0) throw new NoSuchElementException("Priority queue underflow");
55 return pq[1];
56 }
57
58 // return a minimal key
59 public Key minKey() {
60 if (N == 0) throw new NoSuchElementException("Priority queue underflow");
61 return keys[pq[1]];
62 }
63
64 // delete a minimal key and returns its associated index
65 public int delMin() {
66 if (N == 0) throw new NoSuchElementException("Priority queue underflow");
67 int min = pq[1];
68 exch(1, N--);
69 sink(1);
70 qp[min] = -1; // delete
71 keys[pq[N+1]] = null; // to help with garbage collection
72 pq[N+1] = -1; // not needed
73 return min;
74 }
75
76 // return key associated with index k
77 public Key keyOf(int k) {
78 if (!contains(k)) throw new NoSuchElementException("item is not in pq");
79 else return keys[k];
80 }
81
82 // change the key associated with index k
83 public void change(int k, Key key) {
84 changeKey(k, key);
85 }
86
87 // change the key associated with index k
88 public void changeKey(int k, Key key) {
89 if (!contains(k)) throw new NoSuchElementException("item is not in pq");
90 keys[k] = key;
91 swim(qp[k]);
92 sink(qp[k]);
93 }
94
95 // decrease the key associated with index k
96 public void decreaseKey(int k, Key key) {
97 if (!contains(k)) throw new NoSuchElementException("item is not in pq");
98 if (keys[k].compareTo(key) <= 0) throw new RuntimeException("illegal decrease");
99 keys[k] = key;
100 swim(qp[k]);
101 }
102
103 // increase the key associated with index k
104 public void increaseKey(int k, Key key) {
105 if (!contains(k)) throw new NoSuchElementException("item is not in pq");
106 if (keys[k].compareTo(key) >= 0) throw new RuntimeException("illegal decrease");
107 keys[k] = key;
108 sink(qp[k]);
109 }
110
111 // delete the key associated with index k
112 public void delete(int k) {
113 if (!contains(k)) throw new NoSuchElementException("item is not in pq");
114 int index = qp[k];
115 exch(index, N--);
116 swim(index);
117 sink(index);
118 keys[k] = null;
119 qp[k] = -1;
120 }
121
122
123 /**************************************************************
124 * General helper functions
125 **************************************************************/
126 private boolean greater(int i, int j) {
127 return keys[pq[i]].compareTo(keys[pq[j]]) > 0;
128 }
129
130 private void exch(int i, int j) {
131 int swap = pq[i]; pq[i] = pq[j]; pq[j] = swap;
132 qp[pq[i]] = i; qp[pq[j]] = j;
133 }
134
135
136 /**************************************************************
137 * Heap helper functions
138 **************************************************************/
139 private void swim(int k) {
140 while (k > 1 && greater(k/2, k)) {
141 exch(k, k/2);
142 k = k/2;
143 }
144 }
145
146 private void sink(int k) {
147 while (2*k <= N) {
148 int j = 2*k;
149 if (j < N && greater(j, j+1)) j++;
150 if (!greater(k, j)) break;
151 exch(k, j);
152 k = j;
153 }
154 }
155
156
157 /***********************************************************************
158 * Iterators
159 **********************************************************************/
160
161 /**
162 * Return an iterator that iterates over all of the elements on the
163 * priority queue in ascending order.
164 * <p>
165 * The iterator doesn't implement <tt>remove()</tt> since it's optional.
166 */
167 @Override
168 public Iterator<Integer> iterator() { return new HeapIterator(); }
169
170 private class HeapIterator implements Iterator<Integer> {
171 // create a new pq
172 private IndexMinPQ<Key> copy;
173
174 // add all elements to copy of heap
175 // takes linear time since already in heap order so no keys move
176 public HeapIterator() {
177 copy = new IndexMinPQ<>(pq.length - 1);
178 for (int i = 1; i <= N; i++)
179 copy.insert(pq[i], keys[pq[i]]);
180 }
181
182 @Override
183 public boolean hasNext() { return !copy.isEmpty(); }
184 @Override
185 public void remove() { throw new UnsupportedOperationException(); }
186
187 @Override
188 public Integer next() {
189 if (!hasNext()) throw new NoSuchElementException();
190 return copy.delMin();
191 }
192 }
193}
Note: See TracBrowser for help on using the repository browser.