web-dev-qa-db-fra.com

Comment créer Minstl priority_queue?

La file d'attente par défaut de priorité stl est une file d'attente maximale (la fonction Top renvoie l'élément le plus grand).

Disons, pour simplifier, que c'est une file d'attente prioritaire de valeurs int.

95
amitlicht

Utilisation std::greater comme fonction de comparaison:

std::priority_queue<int, std::vector<int>, std::greater<int> > my_min_heap;
172
James McNellis

Une solution consisterait à définir un comparateur approprié avec lequel opérer sur la file d'attente à priorité ordinaire, de telle sorte que sa priorité soit inversée:

 #include <iostream>  
 #include <queue>  
 using namespace std;  

 struct compare  
 {  
   bool operator()(const int& l, const int& r)  
   {  
       return l > r;  
   }  
 };  

 int main()  
 {  
     priority_queue<int,vector<int>, compare > pq;  

     pq.Push(3);  
     pq.Push(5);  
     pq.Push(1);  
     pq.Push(8);  
     while ( !pq.empty() )  
     {  
         cout << pq.top() << endl;  
         pq.pop();  
     }  
     cin.get();  
 }

Ce qui donnerait 1, 3, 5, 8 respectivement.

Quelques exemples d'utilisation de files d'attente prioritaires via STL et implémentations de Sedgewick sont donnés ici .

41
AndyUK

Le troisième paramètre de modèle pour priority_queue est le comparateur. Configurez-le pour utiliser greater.

par exemple.

std::priority_queue<int, std::vector<int>, std::greater<int> > max_queue;

Tu auras besoin #include <functional> pour std::greater.

29
Peter Alexander

Vous pouvez le faire de plusieurs manières:
1. En utilisant greater comme fonction de comparaison:

 #include <bits/stdc++.h>

using namespace std;

int main()
{
    priority_queue<int,vector<int>,greater<int> >pq;
    pq.Push(1);
    pq.Push(2);
    pq.Push(3);

    while(!pq.empty())
    {
        int r = pq.top();
        pq.pop();
        cout<<r<< " ";
    }
    return 0;
}

2. Insérer des valeurs en changeant leur signe (en utilisant moins (-) pour un nombre positif et en utilisant plus (+) pour un nombre négatif:

int main()
{
    priority_queue<int>pq2;
    pq2.Push(-1); //for +1
    pq2.Push(-2); //for +2
    pq2.Push(-3); //for +3
    pq2.Push(4);  //for -4

    while(!pq2.empty())
    {
        int r = pq2.top();
        pq2.pop();
        cout<<-r<<" ";
    }

    return 0;
}

3. Utilisation de la structure ou de la classe personnalisée:

struct compare
{
    bool operator()(const int & a, const int & b)
    {
        return a>b;
    }
};

int main()
{

    priority_queue<int,vector<int>,compare> pq;
    pq.Push(1);
    pq.Push(2);
    pq.Push(3);

    while(!pq.empty())
    {
        int r = pq.top();
        pq.pop();
        cout<<r<<" ";
    }

    return 0;
}

4. En utilisant une structure ou une classe personnalisée, vous pouvez utiliser priority_queue dans n’importe quel ordre. Supposons que nous vou.

    struct people
    {
        int age,salary;

    };
    struct compare{
    bool operator()(const people & a, const people & b)
        {
            if(a.salary==b.salary)
            {
                return a.age>b.age;
            }
            else
            {
                return a.salary>b.salary;
            }

    }
    };
    int main()
    {

        priority_queue<people,vector<people>,compare> pq;
        people person1,person2,person3;
        person1.salary=100;
        person1.age = 50;
        person2.salary=80;
        person2.age = 40;
        person3.salary = 100;
        person3.age=40;


        pq.Push(person1);
        pq.Push(person2);
        pq.Push(person3);

        while(!pq.empty())
        {
            people r = pq.top();
            pq.pop();
            cout<<r.salary<<" "<<r.age<<endl;
    }
  1. Le même résultat peut être obtenu par surcharge de l'opérateur:

    struct people
    {
    int age,salary;
    
    bool operator< (const people & p)const
    {
        if(salary==p.salary)
        {
            return age>p.age;
        }
        else
        {
            return salary>p.salary;
        }
    }};
    

    En fonction principale:

    priority_queue<people> pq;
    people person1,person2,person3;
    person1.salary=100;
    person1.age = 50;
    person2.salary=80;
    person2.age = 40;
    person3.salary = 100;
    person3.age=40;
    
    
    pq.Push(person1);
    pq.Push(person2);
    pq.Push(person3);
    
    while(!pq.empty())
    {
        people r = pq.top();
        pq.pop();
        cout<<r.salary<<" "<<r.age<<endl;
    }
    
18
Taohidul Islam

En C++ 11, vous pouvez également créer un alias pour plus de commodité:

template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;

Et utilisez-le comme ceci:

min_heap<int> my_heap;
16
mechatroner

Une façon de résoudre ce problème consiste à envoyer le négatif de chaque élément dans la priorité_queue afin que le plus grand élément devienne le plus petit élément. Au moment de faire une opération pop, prenez la négation de chaque élément.

#include<bits/stdc++.h>
using namespace std;

int main(){
    priority_queue<int> pq;
    int i;

// Push the negative of each element in priority_queue, so the largest number will become the smallest number

    for (int i = 0; i < 5; i++)
    {
        cin>>j;
        pq.Push(j*-1);
    }

    for (int i = 0; i < 5; i++)
    {
        cout<<(-1)*pq.top()<<endl;
        pq.pop();
    }
}
8
PAVAN BANSAL

Sur la base de toutes les réponses ci-dessus, j'ai créé un exemple de code indiquant comment créer une file d'attente prioritaire. Note: Cela fonctionne avec les compilateurs C++ 11 et supérieurs

#include <iostream>
#include <vector>
#include <iomanip>
#include <queue>

using namespace std;

// template for prirority Q
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;
template<class T> using max_heap = priority_queue<T, std::vector<T>>;

const int RANGE = 1000;

vector<int> get_sample_data(int size);

int main(){
  int n;
  cout << "Enter number of elements N = " ; cin >> n;
  vector<int> dataset = get_sample_data(n);

  max_heap<int> max_pq;
  min_heap<int> min_pq;

  // Push data to Priority Queue
  for(int i: dataset){
    max_pq.Push(i);
    min_pq.Push(i);
  }

  while(!max_pq.empty() && !min_pq.empty()){
    cout << setw(10) << min_pq.top()<< " | " << max_pq.top() << endl;
    min_pq.pop();
    max_pq.pop();
  }

}


vector<int> get_sample_data(int size){
  srand(time(NULL));
  vector<int> dataset;
  for(int i=0; i<size; i++){
    dataset.Push_back(Rand()%RANGE);
  }
  return dataset;
}

sortie du code ci-dessus

Enter number of elements N = 4

        33 | 535
        49 | 411
       411 | 49
       535 | 33
3
ajayramesh

Nous pouvons le faire de plusieurs manières.

Utilisation du paramètre comparateur de modèle

    int main() 
    {
      priority_queue<int, vector<int>, greater<int> > pq;

      pq.Push(40);
      pq.Push(320);
      pq.Push(42);
      pq.Push(65);
      pq.Push(12);

      cout<<pq.top()<<endl;
      return 0;
    }

Utilisation de la classe de compartiment définie utilisée

     struct comp
     {
        bool operator () (int lhs, int rhs)
        {
           return lhs > rhs;
        }
     };

    int main()
    {
       priority_queue<int, vector<int>, comp> pq;

       pq.Push(40);
       pq.Push(320);
       pq.Push(42);
       pq.Push(65);
       pq.Push(12);

       cout<<pq.top()<<endl;

       return 0;
    }
1
rashedcs