【发布时间】:2015-03-12 04:10:43
【问题描述】:
我正在尝试编写一个课程HeapQueue。我将根的左孩子存储在2 * indexOfRoot + 1 索引,右孩子存储在2 * indexOfRoot + 2。
public class HeapQueue implements PriorityQueue, BinaryHeap {
public List<Task> queue;
public Comparator comparator;
public HeapQueue() {
queue = new ArrayList();
}
public void setComparator(Comparator comparator) {
this.comparator = comparator;
heapify(0);
}
public Comparator getComparator() {
return comparator;
}
public void offer(Task task) {
int currentElement, previousElement;
queue.add(task);
currentElement = queue.size() - 1;
previousElement = (currentElement - 1) / 2;
while (previousElement >= 0 &&
getComparator().compare(queue.get(currentElement), queue.get(previousElement)) > 0) {
swap(currentElement, previousElement);
currentElement = previousElement;
previousElement = (currentElement - 1) / 2;
}
}
private void swap(int i, int j) {
Task t1 = queue.get(i);
Task t2 = queue.get(j);
Task t3 = t1;
queue.set(i, t2);
queue.set(j, t3);
}
}
Task的队列存储对象。
public class Task {
private final String name;
private final int priority;
public Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
public int getPriority() {
return priority;
}
@Override
public String toString() {
return name + "\tpriority = " + priority;
}
}
我在HeapQueue 中有一个方法heapify():
public void heapify(int root) {
int leftChild, rightChild;
leftChild = 2 * root + 1;
if (leftChild < queue.size()) {
rightChild = leftChild + 1;
if ((rightChild < queue.size())
&& getComparator().compare(queue.get(rightChild), queue.get(leftChild)) > 0) {
leftChild = rightChild;
}
if (getComparator().compare(queue.get(leftChild), queue.get(root)) > 0) {
swap(root, leftChild);
heapify(leftChild);
}
}
}
将任务添加到队列后,我的任务比较器可能会通过方法setComparator() 进行更改。
默认Comparator 是:
public class Comparator{
public int compare(Task t1, Task t2) {
if (t1.getPriority() == t2.getPriority()) {
return 0;
} else if (t1.getPriority() < t2.getPriority()) {
return -1;
} else {
return 1;
} //sorting max
}
}
例如,其他比较器可能是:
public class otherComparator{
public int compare(Task t1, Task t2) {
if (t1.getPriority() == t2.getPriority()) {
return 0;
} else if (t1.getPriority() < t2.getPriority()) {
return 1;
} else {
return -1;
} //sorting min
}
}
我创建了我的HeapQueue 并添加了一些元素。
HeapQueue heap = new HeapQueue();
heap.setComparator(comparator);
Task t1 = new Task("a", 1);
Task t2 = new Task("b", 2);
Task t3 = new Task("c", 3);
Task t4 = new Task("d", 4);
System.out.println(heap.queue.toString());
结果是:
[d priority = 4, c priority = 3, b priority = 2, a priority = 1]
4
/ \
3 2
/
1
没错。但是当我将Comparator 更改为otherComparator 时:
otherComparator newComparator = new otherComparator();
heap.setComparator(newComparator);
System.out.println(heap.queue.toString());
结果是:
[b priority = 2, c priority = 3, d priority = 4, a priority = 1]
2
/ \
3 4
/
1
这是错误的。正确答案是这样的:
[a priority = 1, b priority = 2, c priority = 3, d priority = 4]
1
/ \
2 3
/
4
我认为heapify() 函数有问题。但我找不到错误。有人可以帮忙吗?
【问题讨论】:
-
可以分享一下你的swap函数吗?
-
@PhamTung 就在那里。
-
嗯,如何将
otherComparator设置为堆的比较器?它没有实现相同的接口? -
@PhamTrung 通过可以更改堆的任务比较器,通过 setComparator(),我可以更改比较器并通过 heapify() 重新构建堆。但它不起作用。
-
我明白了,好的,我现在可以重现这个错误了 :)
标签: java algorithm data-structures heap priority-queue