删除优先级队列的尾部元素

时间:2013-02-27 16:31:21

标签: java priority-queue

如何删除优先级队列的尾部元素?我正在尝试使用优先级队列实现波束搜索,一旦优先级队列已满,我想删除最后一个元素(优先级最低的元素)。

谢谢!

8 个答案:

答案 0 :(得分:5)

没有简单的方法。将元素从原始复制到新的除了最后一个。

PriorityQueue removelast(PriorityQueue pq)
{

    PriorityQueue pqnew;

    while(pq.size() > 1)
    {
        pqnew.add(pq.poll());
    }

    pq.clear();
    return pqnew;
}

称为

pq = removelast(pq);

答案 1 :(得分:5)

您可以使用Guava的MinMaxPriorityQueue来执行此操作。它为队列的两端提供了peek,poll和remove方法。

另一种选择是编写一个强制边界的Queue包装器,类似于this answer。您需要实施offeraddaddAll来检查容量。类似的东西:

public class BoundedQueue<E> implements Serializable, Iterable<E>, Collection<E>, Queue<E> {
    private final Queue<E> queue;
    private int capacity;

    public BoundedQueue(Queue<E> queue, int capacity) {
        this.queue = queue;
        this.capacity = capacity;
    }

    @Override
    public boolean offer(E o) {
        if (queue.size() >= capacity)
            return false;
        return queue.add(o);
    }

    @Override
    public boolean add(E o) throws IllegalStateException {
        if (queue.size() >= capacity)
            throw new IllegalStateException("Queue full"); // same behavior as java.util.ArrayBlockingQueue
        return queue.add(o);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        boolean changed = false;
        for (E o: c)
            changed |= add(o);
        return changed;
    }

    // All other methods simply delegate to 'queue'
}

答案 2 :(得分:2)

使用反相比较器并从头部移除。如果您需要头部和尾部,则使用错误的数据结构。

答案 3 :(得分:2)

我认为,PR的用例是,他需要头部,但也想要一个小PQ,所以想法就是删除尾部。

当PQ实现为映射到数组的二叉树时,头部始终是后备数组的第一个元素(queue[0]),但尾部并不总是在数组的末尾,不得不搜索它。

我认为一个很好的方法是将PQ子类化并编写以下两种方法:

    public class MyPriorityQueue<E> extends PriorityQueue<E>
    {
        // constructors

    public E getTail()
     {
        // queue.length can be bigger than this.size() !!
        Object[] queue = this.toArray();
        E tail = (E)queue[0];
        Comparator<? super E> comparator = this.comparator();
        if (comparator !=null)
           for(int i = 1; i < this.size(); i++)
              if ( comparator.compare(tail, (E)queue[i]) < 0)
                 tail = (E)queue[i];
        else
           for(int j = 1; j < this.size(); j++)
              if ( ((Comparable)tail).compareTo( ((Comparable)queue[j]) ) < 0 )
                 tail = (E)queue[j];
        return tail;
     }  

     public E removeTail()
     {
        E tail = this.getTail();
        this.remove(tail);
        return tail;
     }   
    }

答案 4 :(得分:1)

将数据添加到优先级队列本身时进行比较;

λ> runMaybeT lp_reqInt
Enter an integer..
boru
Enter an integer..
not an integer
Enter an integer..
42
Just 42

答案 5 :(得分:0)

如果您有理由不在内存中生成另一个元素,那么有一个更好的解决方案。

你可以获得队列的大小并用迭代器遍历它,同时计算你要经历的元素,一旦你到达最后一个或你正在寻找的那个,你可以使用PriorityQueue.remove(Object ○)

Iterator<E> it = Queue.iterator();
while (it.hasNext()) {
   temp<E> = it.next();
   counter++;
   if (counter == Queue.size()) {
       Queue.remove(temp);
    }
}

答案 6 :(得分:0)

不支持移除尾巴。

最好的办法是交换元素的顺序,使尾部变为头部,然后remove()代替。

答案 7 :(得分:-2)

如果您关心运行时,我建议您实现自己的队列。我做了以下工作并在我的项目中工作。

1)复制粘贴来自PriorityQueue的代码 - &gt; CustomQueue.java 2)添加方法removeLast() 3)这是我使用的实现(非常小)

public void removeLast() {
    if(size == 0) {
       return;
    }
    queue[size - 1] = null;
    size--;

}

这样做的原因是PriorityQueue的实现使用数组来保存对象。所以&#34;尺寸&#34;实际上是指向数组中下一个可用点的指针。通过减少它,减少了数组/队列的大小,就像丢弃最后一个元素一样。