我正在寻找Java中PQ的一些实现,它允许以PQ顺序迭代 - 首先是元素,接下来是下一个等等。我尝试使用TreeSet(实现NavigableSet)但它会导致一个问题。就我而言:
作为最后一点的结果 - 当我想更新其优先级时,我无法在TreeSet中找到我的元素:/ 你碰巧知道:聪明的方式服从这个吗?或者是以“好”方式迭代的PQ的一些实现?或者我应该创建一些链接数据结构来匹配对象与它们在树中的位置?
更新:
compareTo
方法,因为此优先级不是比较这些对象的正确方法。这就是我需要使用Comparator
可能的解决方案:
PrioritizedObject
,将按优先级进行比较并保留我的对象PrioritizedObject
PrioritizedObject
保留在某些NavigableSet
我会使用此地图从NavigableSet
中删除对象。如果我添加一些内容,当然会用新元素更新它。
问题是我必须从此NavigableSet
包装迭代器以获取迭代器返回我的对象。
有没有更好的解决方案?
答案 0 :(得分:0)
我建议使用ConcurrentSkipListSet
而不是TreeSet
,因为它是线程安全的。如果您知道优先级正在发生变化的对象,则可以调用remove(objToChange)
,更改其优先级,然后将其重新添加到集合中。
要非常小心地将equals
,hashcode
和compareTo
方法依赖于可变字段的任何对象添加到集合中。
编辑:我认为任何解决方案最终都会看起来像PrioritizedObject
这对我来说似乎没问题。如果要迭代对象,请使用Map.keySet
。
答案 1 :(得分:0)
如果并发不是问题,那么您需要做的就是在更新元素的优先级后立即重新排序树。如果我理解问题,这个草图应该适合你。
示例元素:
public class Element implements Comparable<Element> {
private final Integer id;
private Integer priority;
public Element(Integer id, Integer priority) {
this.id = id;
this.priority = priority;
}
@Override
public String toString() {
return "Element{" + "id=" + id + ", priority=" + priority + '}';
}
public Integer getPriority() {
return priority;
}
public void setPriority(Integer priority) {
this.priority = priority;
}
@Override
public int compareTo(Element o) {
if (o == null) {
throw new NullPointerException();
}
return priority.compareTo(o.priority);
}
}
草图:
public class Tree {
public static TreeSet<Element> priorityQueue = new TreeSet<Element>();
public static void dump(TreeSet<Element> in) {
for (Element e : in) {
System.out.println(e);
}
}
public static void updatePriority(Element e, int newPriority) {
if (priorityQueue.remove(e)) {
e.setPriority(newPriority);
priorityQueue.add(e);
}
}
public static void main(String[] args) {
int id;
Element lastElement = null;
for (int i = 0;i < 10 ; i++) {
id = (int)(Math.random()*1000);
priorityQueue.add(lastElement = new Element(id, id));
}
dump(priorityQueue);
updatePriority(lastElement, 0);
System.out.println("updating "+lastElement+ " priority to 0");
dump(priorityQueue);
}
}
您可以通过从treeset中删除元素,设置新优先级然后重新插入来更新元素。此方案的更新操作的复杂性为2*O(log(n)) = O(log(n))
更新:
我能理解的最好的是:你有两个标准需要排序/索引。当我遇到同样的问题时,我使用了这个approach,但this是一个非常有趣的方法,我强烈建议您阅读。
答案 2 :(得分:0)
如果优先级发生变化我知道哪个对象,但我不知道它是先前的优先级
您无需了解其先前的优先级。您所要做的就是将其删除并重新插入。