data_structures_free
This commit is contained in:
128
net/datastructures/HeapPriorityQueue.java
Normal file
128
net/datastructures/HeapPriorityQueue.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package net.datastructures;
|
||||
import java.util.Comparator;
|
||||
|
||||
//begin#fragment HeapPriorityQueue
|
||||
/**
|
||||
* Realization of a priority queue by means of a heap. A complete
|
||||
* binary tree realized by means of an array list is used to
|
||||
* represent the heap.
|
||||
//end#fragment HeapPriorityQueue
|
||||
*
|
||||
* @author Roberto Tamassia, Michael Goodrich, Eric Zamore
|
||||
//begin#fragment HeapPriorityQueue
|
||||
*/
|
||||
public class HeapPriorityQueue<K,V> implements PriorityQueue<K,V> {
|
||||
protected CompleteBinaryTree<Entry<K,V>> heap; // underlying heap
|
||||
protected Comparator<K> comp; // comparator for the keys
|
||||
/** Inner class for heap entries. */
|
||||
protected static class MyEntry<K,V> implements Entry<K,V> {
|
||||
protected K key;
|
||||
protected V value;
|
||||
public MyEntry(K k, V v) { key = k; value = v; }
|
||||
public K getKey() { return key; }
|
||||
public V getValue() { return value; }
|
||||
public String toString() { return "(" + key + "," + value + ")"; }
|
||||
}
|
||||
/** Creates an empty heap with the default comparator */
|
||||
public HeapPriorityQueue() {
|
||||
heap = new ArrayListCompleteBinaryTree<Entry<K,V>>(); // use an array list
|
||||
comp = new DefaultComparator<K>(); // use the default comparator
|
||||
}
|
||||
/** Creates an empty heap with the given comparator */
|
||||
public HeapPriorityQueue(Comparator<K> c) {
|
||||
heap = new ArrayListCompleteBinaryTree<Entry<K,V>>();
|
||||
comp = c;
|
||||
}
|
||||
//end#fragment HeapPriorityQueue
|
||||
/** Sets the comparator used for comparing items in the heap.
|
||||
* @throws IllegalStateException if priority queue is not empty */
|
||||
public void setComparator(Comparator<K> c) throws IllegalStateException {
|
||||
if(!isEmpty()) // this is only allowed if the priority queue is empty
|
||||
throw new IllegalStateException("Priority queue is not empty");
|
||||
comp = c;
|
||||
}
|
||||
//begin#fragment HeapPriorityQueue
|
||||
/** Returns the size of the heap */
|
||||
public int size() { return heap.size(); }
|
||||
/** Returns whether the heap is empty */
|
||||
public boolean isEmpty() { return heap.size() == 0; }
|
||||
//end#fragment HeapPriorityQueue
|
||||
//begin#fragment mainMethods
|
||||
/** Returns but does not remove an entry with minimum key */
|
||||
public Entry<K,V> min() throws EmptyPriorityQueueException {
|
||||
if (isEmpty())
|
||||
throw new EmptyPriorityQueueException("Priority queue is empty");
|
||||
return heap.root().element();
|
||||
}
|
||||
/** Inserts a key-value pair and returns the entry created */
|
||||
public Entry<K,V> insert(K k, V x) throws InvalidKeyException {
|
||||
checkKey(k); // may throw an InvalidKeyException
|
||||
Entry<K,V> entry = new MyEntry<K,V>(k,x);
|
||||
upHeap(heap.add(entry));
|
||||
return entry;
|
||||
}
|
||||
/** Removes and returns an entry with minimum key */
|
||||
public Entry<K,V> removeMin() throws EmptyPriorityQueueException {
|
||||
if (isEmpty())
|
||||
throw new EmptyPriorityQueueException("Priority queue is empty");
|
||||
Entry<K,V> min = heap.root().element();
|
||||
if (size() == 1)
|
||||
heap.remove();
|
||||
else {
|
||||
heap.replace(heap.root(), heap.remove());
|
||||
downHeap(heap.root());
|
||||
}
|
||||
return min;
|
||||
}
|
||||
/** Determines whether a given key is valid */
|
||||
protected void checkKey(K key) throws InvalidKeyException {
|
||||
try {
|
||||
comp.compare(key,key);
|
||||
}
|
||||
catch(Exception e) {
|
||||
throw new InvalidKeyException("Invalid key");
|
||||
}
|
||||
}
|
||||
//end#fragment mainMethods
|
||||
//begin#fragment auxiliary
|
||||
/** Performs up-heap bubbling */
|
||||
protected void upHeap(Position<Entry<K,V>> v) {
|
||||
Position<Entry<K,V>> u;
|
||||
while (!heap.isRoot(v)) {
|
||||
u = heap.parent(v);
|
||||
if (comp.compare(u.element().getKey(), v.element().getKey()) <= 0) break;
|
||||
swap(u, v);
|
||||
v = u;
|
||||
}
|
||||
}
|
||||
/** Performs down-heap bubbling */
|
||||
protected void downHeap(Position<Entry<K,V>> r) {
|
||||
while (heap.isInternal(r)) {
|
||||
Position<Entry<K,V>> s; // the position of the smaller child
|
||||
if (!heap.hasRight(r))
|
||||
s = heap.left(r);
|
||||
else if (comp.compare(heap.left(r).element().getKey(),
|
||||
heap.right(r).element().getKey()) <=0)
|
||||
s = heap.left(r);
|
||||
else
|
||||
s = heap.right(r);
|
||||
if (comp.compare(s.element().getKey(), r.element().getKey()) < 0) {
|
||||
swap(r, s);
|
||||
r = s;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
/** Swaps the entries of the two given positions */
|
||||
protected void swap(Position<Entry<K,V>> x, Position<Entry<K,V>> y) {
|
||||
Entry<K,V> temp = x.element();
|
||||
heap.replace(x, y.element());
|
||||
heap.replace(y, temp);
|
||||
}
|
||||
/** Text visualization for debugging purposes */
|
||||
public String toString() {
|
||||
return heap.toString();
|
||||
}
|
||||
//end#fragment auxiliary
|
||||
}
|
||||
Reference in New Issue
Block a user