我必须实现复杂度为O(log n)的函数,该函数更新优先级队列中元素的优先级。这意味着给定一个元素,对其优先级的访问应该是O(1)。我真的不明白如何做到这一点,如果所有元素都存储在堆中,并且它们的位置不断变化,这使我可以在堆中搜索元素。
堆:
public class Heap<K, V> {
private int size;
private Element<K, V> heap[];
private Comparator<? super K> comparator;
public Heap(Comparator<? super K> comparator) {
//
}
//
public void add(K priority, V value) {
int i;
size++;
if(size > heap.size()) resize();
i = size;
heap[i] = new Element(priority, value);
while(i > 0 || comparator.compare(heap[parent(i)].priority, heap[i].priority) < 0) {
swap(i, parent(i));
}
}
// O(log n)
public void updatePriority(int i, K priority) {
K oldPriority = heap[i].priority;
heap[i] = new Element(priority, heap[i].value);
if(comparator.compare(oldPriority, heap[i].priority) > 0) {
heapify(i);
} else {
while(i > 0 && comparator.compare(heap[parent(i)].priority, heap[i].priority)) < 0) {
swap(i, parent(i));
i = parent(i);
}
}
}
}
的PriorityQueue:
public class PriorityQueue<K, V> {
private Heap<Element<K, V>> heap;
private Comparator<? super K> comparator;
public PriorityQueue(Comparator<? super K> comparator) {
heap = new Heap<K, V>(comparator);
}
//
// Should be O(log n)
public void updatePriority(K priority, V elem) {
// get index of elem in O(1)
heap.updatePriority(indexOfElem, priority);
}
}
元素:
public class Element<K, V> {
public K priority;
public V value;
public Element(K priority, V value) {
this.priority = priority;
this.value = value;
}
}
此优先级队列应该用于实现Prim的算法。那么我该怎样才能获得O(1)访问复杂性?
答案 0 :(得分:0)
我可以想到两种方法:
Map<V, Integer>
。这意味着一些额外的簿记,但它不会太坏,因为您需要在主阵列中添加或移动元素时完全更新它,这样您就可以轻松地将其放入操作数组时总是使用的单setElement
方法。 (你甚至可以将数组本身移动到一个处理它的辅助类中。)Map<V, Element<K, V>>
映射到当前元素来执行此操作。你可以添加一个明确的&#34;删除&#34;如果某个元素的值不再映射到Element
,则只需将该元素计为已删除的Map<V, Element<K, V>>
。答案 1 :(得分:0)
您的add
方法存在错误。这一行:
while(i > 0 || comparator.compare(heap[parent(i)].priority, heap[i].priority) < 0) {
||
应为&&