Die Klasse PriorityQueue implementiert eine Prioritätenliste. PriorityQueue speichert Paare (Zahlenwert, Objekt), die mit der Funktion insert eingegeben werden. Mit der Funktion extract wird jeweils das Paar mit dem höchsten Zahlenwert zurückgegeben und aus der Liste gelöscht.
Die Prioritätenliste ist als binärer Baum mit der Eigenschaft eines Heaps organisiert. Sowohl insert als auch extract benötigen O(log(n)) Schritte, wobei n die Anzahl der Einträge in der Prioritätenliste ist.
Beim Aufruf des Konstruktors wird mit dem Parameter updown = 1 oder updown = -1 festgelegt, ob mit extract das Paar mit dem höchsten oder mit dem niedrigsten Zahlenwert zurückgegeben werden soll.
import java.util.ArrayList;
public class PriorityQueue<Type>
{
private ArrayList<Pair<Double, Type>> a;
private int updown;
public PriorityQueue(int updown_)
{
a=new ArrayList<Pair<Double, Type>>();
updown=updown_;
}
public PriorityQueue()
{
this(1);
}
public void insert(double p, Type x)
{
a.add(new Pair<Double, Type>(p, x));
upheap();
}
public Pair<Double, Type> extract()
{
Pair<Double, Type> z;
exchange(root(), lastLeaf());
z=a.remove(lastLeaf());
downheap();
return z;
}
public Type extractObj()
{
return extract().get1();
}
private void upheap()
{
int u, v=lastLeaf();
while (!isRoot(v))
{
u=pred(v);
if (p(u)>=p(v))
return;
exchange(u, v);
v=u;
}
}
private void downheap()
{
int w, v=root();
while (!isLeaf(v))
{
w=succ(v);
if (exists(w+1))
if (p(w+1)>p(w))
w++;
if (p(v)>=p(w))
return;
exchange(v, w);
v=w;
}
}
private Pair<Double, Type> get(int v)
{
return a.get(v);
}
private double p(int v)
{
return updown*get(v).get0();
}
private void exchange(int i, int j)
{
Pair<Double, Type> h=a.get(i);
a.set(i, a.get(j));
a.set(j, h);
}
private int root()
{
return 0;
}
private int lastLeaf()
{
return size()-1;
}
private int pred(int v)
{
return (v-1)/2;
}
private int succ(int v)
{
return v*2+1;
}
private boolean isRoot(int v)
{
return v==0;
}
private boolean isLeaf(int v)
{
return v>=size()/2;
}
private boolean exists(int v)
{
return v<size();
}
public boolean isEmpty()
{
return a.isEmpty();
}
public int size()
{
return a.size();
}
}
Mit folgendem Testprogramm lässt sich die Klasse PriorityQueue vom Typ -1 testen.
import junit.framework.TestCase;
public class TestPriorityQueue extends TestCase
{
public void testPriorityQueue()
{
PriorityQueue<String> pq=new PriorityQueue<String>(-1);
pq.insert(3, "3");
pq.insert(5, "5");
pq.insert(-2, "-2");
pq.insert(5, "5");
pq.insert(-2, "-2");
pq.insert(1, "1");
System.out.println(pq.extractObj());
System.out.println(pq.extractObj());
System.out.println(pq.extractObj());
System.out.println(pq.extractObj());
System.out.println(pq.extractObj());
System.out.println(pq.extractObj());
}
}
Die Klasse PriorityQueue verwendet Objekte vom Typ Pair zur Speicherung der Paare (Zahlenwert, Objekt).
public class Pair<TypA, TypB>
{
private TypA u;
private TypB v;
public Pair(TypA u_, TypB v_)
{
u=u_;
v=v_;
}
public TypA get0()
{
return u;
}
public TypB get1()
{
return v;
}
public boolean equals(Pair<TypA, TypB> other)
{
return get0().equals(other.get0()) && get1().equals(other.get1());
}
public String toString()
{
return "("+u+", "+v+")";
}
}