刚刚完成用LinkedList
编写此实现。我知道这是一个初学者实现。肯定有很多错误。我只是想知道是否有人可以告诉我insert(K key, V value)
方法的最坏情况的成本。我应该留在O(n)吗?
使用addLast()
中的getLast()
和LinkedList
方法进行了编辑,并使用ListIterator
代替Iterator
。
公共类SortedListPriorityQueue实现PriorityQueue {
protected List<Entry<K,V>> entries;
protected Comparator<K> c;
private static class MyEntry<K,V> implements Entry<K,V>{
protected K key;
protected V value;
public MyEntry(K key, V value){
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
}
/**
* Crea la coda con il comparatore DefaultComparator
*/
public SortedListPriorityQueue() {
entries = new LinkedList<Entry<K,V>>();
c = new DefaultComparator<K>();
}
/* Utilizza un comparatore specifico
public SortedListPriorityQueue(Comparator<K> comp) {}
*/
@Override
public int size() {
return entries.size();
}
@Override
public boolean isEmpty() {
return entries.isEmpty();
}
@Override
public Entry<K, V> min() {
if(entries.isEmpty()) throw new RuntimeException("Priority queue is empty");
else return entries.get(0);
}
@Override
public Entry<K, V> removeMin() {
if(entries.isEmpty()) throw new RuntimeException("Priority queue is empty");
else return entries.remove(0);
}
@Override
public Entry<K, V> insert(K key, V value) {
Entry<K,V> new_entry = new MyEntry<K,V>(key, value);
insertEntry(new_entry);
return new_entry;
}
private void insertEntry(Entry<K, V> e) {
//caso base1: lista vuota
if(entries.isEmpty()){
entries.add(e);
return;
}
// caso base2: inserisce alla fine della lista
else if(c.compare(e.getKey(), ((LinkedList<Entry<K, V>>) entries).getLast().getKey()) > 0){
((LinkedList<Entry<K,V>>) entries).addLast(e);
return;
}
ListIterator<Entry<K,V>> it = entries.listIterator();
Entry<K,V> current = null;
while(it.hasNext()){
current = it.next();
if(c.compare(e.getKey(), current.getKey()) < 0){
it.add(e);
return;
}
}
}
}
答案 0 :(得分:2)
是的,您的最坏情况插入时间是O(n)
- 插入列表末尾附近的内容。您花费O(n)
时间来查找正确的索引,然后在O(n)
内LinkedList.add
时间插入它。
答案 1 :(得分:1)
优先级队列可以使用堆实现
实现O(log n)插入答案 2 :(得分:0)
最坏情况的成本是线性的,它取决于您拥有的条目数量-1,因为它必须在列表中的最后一个元素之前插入。所以它是O(n)。
答案 3 :(得分:0)
是的,它是O(n)
。
但请注意,n
的常数乘数并非最佳,因为get(int)
的{{1}}和add(int, T)
也是LinkedList
,但您可以替换他们使用O(n)
次操作 - O(1)
,getLast()
和addLast()
。也就是说,现在需要ListIterator.add()
个步骤来查找新条目的位置,并O(n)
步骤实际插入它,但您可以修改您的实现以在O(n)
中找到一个位置并插入在O(n)
。
这样的替换不会改变算法的渐近复杂度(它仍然是O(1)
),但它会改善算法的典型实际性能。
当然,对于实际应用,最好使用基于堆的实现(例如内置的实现)来提供O(n)
插入和删除。