web-dev-qa-db-ja.com

priority_queueから先頭にない要素を削除する方法は?

私のプログラムでは、最上位にない優先度キューから要素を削除する必要があります。それはできますか?そうでない場合は、独自のヒープを作成する以外の方法を提案してください。

28
ishan3243

標準 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

26
alexm

PradipとMAShは、削除操作を実現する時間を犠牲にします。ただし、時間の複雑さが重要な場合は、ハッシュmin_heapを使用することをお勧めします。ハッシュテーブルには値ポインタが格納され、ポインタはmin_heapを指します。つまり、O(1)時間を費やしてmin_heapの値を見つけ、O(log(n))を使用して要素を削除(シフトアップまたはシフトダウン)できます。

4
Y. Xu

最善の解決策は、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);
1
Amit Kumar