Как удалить элемент не сверху с priority_queue?

В моей программе мне нужно удалить элемент из очереди приоритетов, которая не находится наверху. Это можно сделать? Если нет, предложите способ сделать это, кроме создания собственной кучи.

Ответы

Ответ 1

Стандарт priority_queue<T> можно настроить с помощью наследования. Он защищал членов c и comp, на которые можно ссылаться в классе потомков.

template<typename T>
class custom_priority_queue : public std::priority_queue<T, std::vector<T>>
{
  public:

      bool remove(const T& value) {
        auto it = std::find(this->c.begin(), this->c.end(), value);
        if (it != this->c.end()) {
            this->c.erase(it);
            std::make_heap(this->c.begin(), this->c.end(), this->comp);
            return true;
       }
       else {
        return false;
       }
 }
};

void main()
{
   custom_priority_queue<int> queue;

   queue.push(10);
   queue.push(2);
   queue.push(4);
   queue.push(6);
   queue.push(3);

   queue.remove(6);

   while (!queue.empty())
   {
      std::cout << queue.top();
      queue.pop();

      if (!queue.empty())
      {
        std::cout << ", ";
      }
   }

 }

Вывод:

10, 4, 3, 2

Ответ 2

Pradip и MASh пожертвуют временем, чтобы реализовать операцию удаления. Но если для вас важна временная сложность, я предлагаю вам использовать hash min_heap. В таблице Hash хранится указатель на значение, а указатели указывают на min_heap. Это означает, что вы можете потратить время O (1), чтобы найти значение в min_heap и O (log (n)) для удаления (просеивания или просеивания) элемента.

Ответ 3

Лучшее решение - использовать std :: set. Наборы предоставляют методы, которые позволяют использовать его как кучу мин/макс (или очередь с приоритетами).

std::set<int> pq;

//accessing the smallest element(use as min heap)
*pq.begin();

//accessing the largest element (use as max heap)
*pq.rbegin();

Кроме того, наборы также позволяют случайное удаление.

//to delete the integer '6'
auto it = pq.find(6);
pq.erase(it);

Ответ 4

Позволяет удалить 5-й элемент в priority_queue<type> Q. Затем вы можете сделать это следующим образом:

vector<type> tempQ;
int i=0;
int n=5;
type t;
while(i<n-1)
{
    tempQ.push_back(Q.top());
    Q.pop();        
    i++;
}
Q.pop();
i=0;
while(i<n-1)
{
    t=tempQ[i++];
    Q.push(t);
}