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.
Utilisation std::greater
comme fonction de comparaison:
std::priority_queue<int, std::vector<int>, std::greater<int> > my_min_heap;
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 .
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
.
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;
}
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;
}
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;
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();
}
}
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
Nous pouvons le faire de plusieurs manières.
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;
}
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;
}