Reputation: 908
I am trying to write a generic heap class.
import java.util.ArrayList;
public class heap<T extends Comparable<T>>
{
private ArrayList<T> h;
private int size;
public heap()
{
h = new ArrayList<T>();
h.add(null);
size = 0;
}
public T getMin()
{
return h.get(1);
}
public T popMin()
{
T tmp = getMin();
h.set(1, h.get(size));
size--;
sift(1);
return tmp;
}
public void insert(T key)
{
h.add(key);
percolate(++size);
}
public int getSize()
{
return this.size;
}
private int getLeftSon(int i)
{
return (i<<1<=size)? i<<1 : 0;
}
private int getRightSon(int i)
{
return ((i<<1)+1<=size)? (i<<1)+1 : 0;
}
private int getFather(int i)
{
return ((i>>1)!=0)? i>>1 : 0;
}
private void swap(int i, int j)
{
T tmp = h.get(i);
h.set(i, h.get(j));
h.set(j, tmp);
}
private void sift(int i)
{
int son;
do {
son = 0;
if (getLeftSon(i) != 0)
{
son = getLeftSon(i);
if (getRightSon(i) != 0 && h.get(getRightSon(i)).compareTo(h.get(getLeftSon(i))) > 0)
son = getRightSon(i);
if (h.get(son).compareTo(h.get(i)) <= 0)
son = 0;
}
if (son!=0) {
swap(i, son);
i = son;
}
} while (son!=0);
}
private void percolate(int i)
{
T key = h.get(i);
while ((i > 1) && (key.compareTo(h.get(getFather(i))) > 0))
{
h.set(i, h.get(getFather(i)));
i = getFather(i);
}
h.set(i, key);
}
}
All good. It works like a charm. Excepting one thing: if I work with Integers I don't have 'access' to the method compareTo
from Integer. meaning that I can not override it's behaviour. I will always have a Max heap this way. Can Integer compareTo
by override (I don't think it can)?
So what can I do apart from creating another class MyInteger extends Integer{...}
and override it there.
Upvotes: 1
Views: 503
Reputation: 12440
You could make your heap accept a Comparator in constructor and then provide a Comparator that reverses the order.
That's what the Comparator is for actually - defining an ordering that's not a natural one for the given class, being able to define multiple orderings of the same class, or indeed defining an ordering for a class you cannot modify.
The approach of accepting a comparator at construction time can be seen in TreeSet for example.
Example code stub:
public class Heap<T> { /* no need for items to extend Comparable anymore */
private final Comparator<T> cmp;
public Heap(Comparator<T> cmp) {
this.cmp = cmp;
...
}
...
}
... and then use cmp.compare(item1, item2)
wherever you now use item2.compareTo(item2)
.
Upvotes: 8