Как удалить хвостовой элемент приоритетной очереди? Я пытаюсь реализовать поиск луча, используя очередь приоритетов, и как только очередь приоритетов заполнена, я хочу удалить последний элемент (элемент с наименьшим приоритетом).
Спасибо!
Как удалить хвостовой элемент приоритетной очереди? Я пытаюсь реализовать поиск луча, используя очередь приоритетов, и как только очередь приоритетов заполнена, я хочу удалить последний элемент (элемент с наименьшим приоритетом).
Спасибо!
Нет простого пути. Скопируйте элементы из оригинала в новый, кроме последнего.
PriorityQueue removelast(PriorityQueue pq)
{
PriorityQueue pqnew;
while(pq.size() > 1)
{
pqnew.add(pq.poll());
}
pq.clear();
return pqnew;
}
называется как
pq = removelast(pq);
Возможно, вы могли бы использовать MinMaxPriorityQueue от Guava. для этого. Он предоставляет методы просмотра, опроса и удаления для обоих концов очереди.
Другой вариант — написать оболочку Queue, обеспечивающую ограничение, подобно этому ответу. Вам нужно будет реализовать offer
, add
и addAll
для проверки емкости. Что-то типа:
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'
}
Используйте инвертирующий компаратор и снимите его с головы. Если вам нужны и голова, и хвост, вы используете неправильную структуру данных.
Я думаю, вариант использования 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;
}
}
Пока вы добавляете данные в очередь приоритетов, сами выполняйте сравнение;
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Collections.reverseOrder());
Есть лучшее решение, если у вас есть причина не генерировать еще один элемент в память.
вы можете получить размер очереди и запустить ее с помощью итератора, подсчитывая элементы, которые вы просматриваете, как только вы доберетесь до последнего ИЛИ того, который вы ищете, вы можете использовать PriorityQueue.remove(Object o)
Iterator<E> it = Queue.iterator();
while (it.hasNext()) {
temp<E> = it.next();
counter++;
if (counter == Queue.size()) {
Queue.remove(temp);
}
}
Удаление хвоста не поддерживается.
Лучшее, что вы можете сделать, это изменить порядок элементов так, чтобы хвост стал головой, а вместо этого remove()
.
Если вас беспокоит среда выполнения, я предлагаю реализовать собственную очередь. Я сделал следующее и работал над своим проектом.
1) скопируйте и вставьте код из PriorityQueue -> CustomQueue.java 2) Добавьте метод removeLast() 3) Это реализация, которую я использовал (очень минимальная)
public void removeLast() {
if(size == 0) {
return;
}
queue[size - 1] = null;
size--;
}
Причина, по которой это работает, заключается в том, что реализация PriorityQueue использует массив для хранения объекта. Таким образом, «размер» фактически является указателем на следующее доступное место в массиве. Уменьшая его, размер массива/очереди уменьшается, как будто вы отбрасываете последний элемент.
PriorityQueue
и переместить все элементы из начальной очереди в новую, кроме хвоста. - person Luiggi Mendoza   schedule 27.02.2013