我正在尝试编写一个通用的堆类.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
都好.它就像一个魅力.除了一件事:如果我使用Integers,我没有compareTo从Integer "访问"该方法.意思是我无法覆盖它的行为.我将永远以这种方式拥有Max堆.可以compareTo通过覆盖整数(我不认为它可以)?那么除了创建另一个class MyInteger extends Integer{...}并在那里覆盖它,我还能做些什么.
您可以使堆在构造函数中接受Comparator,然后提供反转顺序的Comparator.
这就是比较器实际上的用途 - 定义一个对于给定类不是自然的排序,能够定义同一个类的多个排序,或者确定为您无法修改的类定义排序.
例如,可以在TreeSet中看到在构造时接受比较器的方法.
示例代码存根:
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;
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
......然后cmp.compare(item1, item2)在现在使用的任何地方使用item2.compareTo(item2).