AuD
Lecture 'Algorithmen und Datenstrukturen' (code examples)
PriorityQueue.java
Go to the documentation of this file.
1package aud;
2
3import java.util.Comparator;
4
6
46public class PriorityQueue<T> extends AbstractPriorityQueue<T> {
47
48 // TODO define unit test for PriorityQueue
49 // TODO Is it better to "outsource" the mapping? (public upheap, downheap)?
50
52 private static final int MINENTRIES=64;
53
56 Vector<T> heap_;
57
59 HashMap<T,Integer> position_;
60
65 public PriorityQueue(int n,Comparator<T> cmp) {
66 super(cmp);
67 heap_=new Vector<T>();
68 heap_.reserve(n);
69 position_=new HashMap<T,Integer>(n);
70 }
71 public PriorityQueue(Comparator<T> cmp) { this(MINENTRIES,cmp); }
72
73 public PriorityQueue(int n) { this(n,null); }
74 public PriorityQueue() { this(MINENTRIES,null); }
75
76 @Override public T front() {
77 return heap_.front(); // may throw
78 }
79
80 @Override public boolean is_empty() {
81 return heap_.empty();
82 }
83
85 public boolean contains(T x) { return position_.contains(x); }
86
88 public int size() { return heap_.size(); }
89
90 @Override public T pop() {
91 T root=heap_.front(); // may throw
92 position_.remove(root);
93
94 if (heap_.size()>1) {
95 position_.insert((heap_.data_[0]=heap_.back()),0);
96 heap_.pop_back();
97 downheap(0);
98 }
99 else
100 heap_.pop_back();
101
102 return root;
103 }
104
106 int getParent(int k) { return ((k+1)/2)-1; }
108 int getLeftChild(int k) { return ((k+1)*2)-1; }
110 boolean less(int i,int j) {
111 return super.less(heap_.at(i),heap_.at(j));
112 }
114 boolean leq(int i,int j) {
115 if (less(i,j)) return true;
116 else return !less(j,i); // symmetric test fails for equality
117 }
119 boolean less(T x,int k) {
120 return super.less(x,heap_.at(k));
121 }
123 void move(int from,int to) {
124 T x=heap_.data_[from];
125 heap_.data_[to]=x;
126 position_.insert(x,to);
127 }
129 void set(int k,T x) {
130 heap_.data_[k]=x;
131 position_.insert(x,k);
132 }
133
135 void downheap(int k) {
136 T x=heap_.data_[k];
137 int j=getLeftChild(k);
138
139 while (j<heap_.size()) {
140 if (j<heap_.size()-1 && less(j+1,j)) j=j+1;
141 if (less(x,j)) break;
142 move(j,k);
143 k=j;
144 j=getLeftChild(k);
145 }
146 set(k,x);
147 }
148
153 @Override public void push(T x) {
154 if (contains(x))
155 throw new RuntimeException(x.toString()+" already contained in PQ");
156
157 int k=heap_.size();
158 heap_.push_back(x);
159 position_.insert(x,k);
160 upheap(k);
161 }
162
164 void upheap(int k) {
165 if (k>0) {
166 T x=heap_.data_[k];
167 int p;
168 while (k>0 && less(x,p=getParent(k))) {
169 move(p,k);
170 k=p;
171 }
172 set(k,x);
173 }
174 }
175
177 public void raise(T x) {
178 assert(position_.contains(x));
179 int k=position_.find(x);
180
181 assert(k==0 || less(getParent(k),k)); // priority was raised!
182
183 downheap(k);
184 }
185
187 public void lower(T x) {
188 assert(position_.contains(x));
189 int k=position_.find(x);
190
191 // Assert that priority was lowered!
192 assert(getLeftChild(k) >=heap_.size() || less(k,getLeftChild(k)));
193 assert(getLeftChild(k)+1>=heap_.size() || less(k,getLeftChild(k)+1));
194
195 upheap(k);
196 }
197
198 @Override public String toString() {
199 return position_.toString();
200 }
201
203 public void checkConsistency() {
204 System.err.println("size="+heap_.size());
205 // check mapping between heap_ and position_
206 if (heap_.size()!=position_.size())
207 throw new RuntimeException("size mismatch");
208 for (int i=0;i<heap_.size();++i)
209 if (position_.find(heap_.at(i))==null || position_.find(heap_.at(i))!=i)
210 throw new RuntimeException("invalid mapping for key='"+heap_.at(i)+"'");
211
212 // check heap property
213 for (int i=0;i<heap_.size();++i) {
214 if (i>0) {
215 int p=getParent(i);
216 if (!leq(p,i))
217 throw new RuntimeException("heap property violated (parent");
218 }
219 int left=getLeftChild(i);
220 if (left<heap_.size()) {
221 if (!leq(i,left))
222 throw new RuntimeException("heap property violated (left)");
223
224 int right=left+1;
225 if (right<heap_.size()) {
226 if (!leq(i,right))
227 throw new RuntimeException("heap property violated (right)");
228 }
229 }
230 }
231 }
232
234 public static void main(String[] args) {
235
236 {
237 // use as a "standard" priority queue
238
240
241 pq.push(2); System.out.println(pq);
242 pq.push(4); System.out.println(pq);
243 pq.push(3); System.out.println(pq);
244 pq.push(1); System.out.println(pq);
245
246 System.out.println(pq.pop());
247 System.out.println(pq);
248
249 System.out.println(pq.pop());
250 System.out.println(pq);
251 }
252 {
253 // now the following provides a mapping from entries to priorities
255 priority.insert("a",1);
256 priority.insert("b",2);
257 priority.insert("c",3);
258 priority.insert("d",4);
259
262 (new Comparator<String>() {
263 @Override public int compare(String a,String b) {
264 return priority.find(a)-priority.find(b);
265 }
266 });
267
268 // first we do the same as above
269
270 pq.push("b"); System.out.println(pq);
271 pq.push("d"); System.out.println(pq);
272 pq.push("c"); System.out.println(pq);
273 pq.push("a"); System.out.println(pq);
274
275 System.out.println(pq.pop());
276 System.out.println(pq);
277
278 System.out.println(pq.pop());
279 System.out.println(pq);
280
281 // restore what we had before
282 pq.push("b"); System.out.println(pq);
283 pq.push("a"); System.out.println(pq);
284
285 // now we gonna change the priority mapping and update pq
286
287 System.out.println("front="+pq.front());
288 priority.insert("a",5); // RAISE priority ...
289 System.out.println("new prioities: "+priority);
290 pq.raise("a"); // ... and update pq
291 System.out.println("front="+pq.front());
292 priority.insert("c",0); // LOWER priority ...
293 System.out.println("new prioities: "+priority);
294 pq.lower("c"); // ... and update pq
295 System.out.println("front="+pq.front());
296 }
297 }
298
299}
Implementation of an unordered map based on a hash table.
Definition: HashMap.java:31
Value insert(Key key, Value value)
insert key-value pair
Definition: HashMap.java:260
Value find(Key key)
find value for key @endiliteral
Definition: HashMap.java:281
String toString()
Definition: HashMap.java:299
Value remove(Key key)
remove entry (equivalent to insert(key,null))
Definition: HashMap.java:273
boolean contains(Key key)
Is key contained in map?
Definition: HashMap.java:295
int size()
get current number of entries
Definition: HashMap.java:153
Priority queue based on binary min-heap.
int size()
get number of entries
boolean is_empty()
Is PQ empty?
void push(T x)
Add entry to PQ.
void checkConsistency()
check consistency
boolean contains(T x)
Is x contained in PQ?
PriorityQueue(int n, Comparator< T > cmp)
Create empty priority queue.
PriorityQueue(Comparator< T > cmp)
void raise(T x)
update heap after raising priority of x
T pop()
Pop minimal element from PQ.
T front()
Get minimal element.
void lower(T x)
update heap after lowering priority of x
static void main(String[] args)
example and test
Implementation of an array-based vector.
Definition: Vector.java:44
void pop_back()
remove last enytry [O(1)]
Definition: Vector.java:182
T back()
get last entry [O(1)]
Definition: Vector.java:84
void push_back(T obj)
insert new entry obj at the end [O(1) for sufficient capacity]
Definition: Vector.java:155
T at(int i)
get i-th entry [O(1)]
Definition: Vector.java:92
int size()
get number of entries [O(1)]
Definition: Vector.java:60
T front()
get first entry [O(1)]
Definition: Vector.java:78
void reserve(int n)
Ensure capacity for n entries.
Definition: Vector.java:120
boolean empty()
Is vector empty? [O(1)].
Definition: Vector.java:73
Interface for an ADT priority queue.
abstract data types
AuD lecture: Data structures, algorithms, examples.
Definition: A234Tree.java:1