Explication détaillée de c++priority_queue

explication détaillée de la file d'attente prioritaire

définition

1. L'adaptateur de conteneur priority_queue simule également la structure de stockage d'une file d'attente, c'est-à-dire que l'utilisation de cet adaptateur de conteneur pour stocker des éléments ne peut "entrer que par une extrémité (appelée queue de file d'attente) et sortir par l'autre extrémité (appelée tête de file d'attente) ", et à chaque fois seulement Peut accéder à l'élément en tête de priority_queue. Cependant, le stockage et la récupération des éléments dans l'adaptateur de conteneur priority_queue ne suivent pas le principe "First in, First out", mais le principe "First in, Largest out". La traduction simple signifie que les éléments de la file d'attente avancée ne sortent pas nécessairement de la file d'attente en premier, mais les éléments avec la priorité la plus élevée sortent de la file d'attente en premier.

  注意,“First in,Largest out”原则是笔者为了总结 priority_queue 存取元素的特性自创的一种称谓,仅为了方便读者理解。

2. Par exemple, supposons qu'il existe actuellement un adaptateur de conteneur priority_queue et que la règle de tri formulée par celui-ci consiste à trier en fonction de la valeur de l'élément de grand à petit. Selon cette règle, il est naturel que l'élément avec la valeur la plus élevée dans priority_queue ait la priorité la plus élevée.

3. Afin de s'assurer que l'adaptateur de conteneur priority_queue supprime à chaque fois l'élément avec la priorité la plus élevée de la tête de la file d'attente, chaque fois qu'un nouvel élément entre, il trouvera l'élément avec la priorité la plus élevée selon les règles de tri établies et déplacera à la tête de la file d'attente ; de même, lorsque priority_queue supprime un élément de la tête de la file d'attente, il trouvera l'élément avec la priorité actuelle la plus élevée et le déplacera vers la tête de la file d'attente. Sur la base de cette fonctionnalité de priority_queue, l'adaptateur de conteneur est appelé une file d'attente prioritaire.
Dans STL, l'adaptateur de conteneur priority_queue est défini comme suit :

template <typename T,
        typename Container=std::vector<T>,
        typename Compare=std::less<T> >
class priority_queue{
    
    
    //......
}

On peut voir que la classe de modèle d'adaptateur de conteneur priority_queue peut transmettre jusqu'à 3 paramètres, et leurs significations respectives sont les suivantes :
typename T : spécifie le type spécifique d'élément de stockage ;
typename Container : spécifie le conteneur sous-jacent utilisé par priority_queue, et utilise le conteneur vectoriel par défaut.

 注: 作为 priority_queue 容器适配器的底层容器,其必须包含 empty()、size()、front()、push_back()、
  pop_back() 这几个成员函数,STL 序列式容器中只有 vector 和 deque 容器符合条件。

typename Compare : spécifie les règles de tri pour évaluer la priorité des éléments dans le conteneur. Par défaut, std::less est utilisé pour trier les valeurs des éléments de grand à petit. Vous pouvez également utiliser std::greater pour trier l'élément valeurs de petit à grand, mais plus Le cas est d'utiliser un classement personnalisé.
Parmi eux, std::less et std::greater sont tous deux définis dans le fichier d'en-tête en tant qu'objets fonction.

Plusieurs façons de créer priority_queue

Étant donné que le modèle d'adaptateur de conteneur priority_queue se trouve dans le fichier d'en-tête et est défini dans l'espace de noms std, les 2 lignes de code suivantes doivent être incluses dans le programme avant de tenter de créer ce type de conteneur :

#include <queue>
 using namespace std;

La méthode de création d'un adaptateur de conteneur priority_queue :
1. Créez un adaptateur de conteneur priority_queue vide, la couche inférieure adopte le conteneur vectoriel par défaut et la méthode de tri adopte également la méthode std ::less par défaut :

std::priority_queue<int> values;

2. L'adaptateur de conteneur priority_queue peut être initialisé à l'aide de tableaux ordinaires ou de données dans une plage spécifiée dans d'autres conteneurs :

//使用普通数组
int values[]={
    
    4,2,3,1};
std::priority_queue<int>copy_values(values,values+4);//{4,2,3,1}
//使用序列式容器
std::array<int,4>values{
    
     4,2,3,1 };
std::priority_queue<int>copy_values(values.begin(),values.end());//{4,2,3,1}

Notez que les deux méthodes ci-dessus doivent garantir que le type d'élément stocké dans le tableau ou le conteneur est le même que le type de stockage spécifié par priority_queue. De plus, les données du tableau ou du conteneur utilisé pour l'initialisation n'ont pas besoin d'être triées, priority_queue les triera automatiquement.
3) Vous pouvez également spécifier manuellement le conteneur sous-jacent et les règles de tri utilisées par priority_queue, telles que :

int values[]{
    
     4,1,2,3 };
std::priority_queue<int, std::deque<int>, std::greater<int> >copy_values(values, values+4);//{1,2,3,4}

Fonctions membres fournies par priority_queue

fonction membre Fonction
vide() Si la file d'attente prioritaire est vide, renvoie vrai ; sinon, renvoie faux.
taille() Renvoie le nombre d'éléments stockés dans priority_queue.
haut() Renvoie la forme de référence du premier élément dans priority_queue
pousser (const T & obj) Stocke une copie de l'élément obj dans la position appropriée dans priority_queue selon les règles d'ordre établies.
pousser(T&& obj) Déplacez et stockez l'élément obj à une position appropriée dans priority_queue conformément aux règles d'ordre établies.
remplacer ( Args & & ... args ) Args&&... args représentent les données nécessaires pour construire un élément de type stockage (pour un objet de classe, plusieurs données peuvent être nécessaires pour construire un objet). La fonction de cette fonction est de générer directement le nouvel élément à la position appropriée de l'adaptateur de conteneur selon les règles de classement établies.
populaire() Supprime le premier élément de l'adaptateur de conteneur priority_queue.
swap(priority_queue& autre) Échangez les éléments dans les deux adaptateurs de conteneurs priority_queue. Il convient de noter que les types d'éléments stockés dans les deux adaptateurs de conteneurs priority_queue à échanger et les types de conteneurs de base utilisés en bas doivent être les mêmes.
和 queue 一样,priority_queue 也没有迭代器,因此访问元素的唯一方式是遍历容器,
通过不断移除访问过的元素,去访问下一个元素。

La méthode de tri de priority_queue et le tri personnalisé

Moins devient un gros tas supérieur (de la couche supérieure à la couche inférieure, les éléments du tas sont de grands à petits, et la même couche est aléatoire) plus grand devient
un petit tas supérieur (de la couche supérieure à la couche inférieure, le tas les éléments sont de petit à grand, et la même couche est aléatoire) )
Tout d'abord, que la file d'attente prioritaire stocke des types de données de base (int, double, etc.), ou des objets de classe de chaîne ou des objets de classe personnalisés, vous pouvez utiliser des objets de fonction pour personnaliser les règles de tri. Par exemple:


#include<iostream>
#include<queue>
using namespace std;
//函数对象类
template <typename T>
class cmp
{
    
    
public:
    //重载 () 运算符
    bool operator()(T a, T b)
    {
    
    
        return a > b;
    }
};
 
int main()
{
    
    
    int a[] = {
    
     4,2,3,5,6 };
    priority_queue<int,vector<int>,cmp<int> > pq(a,a+5);//第三个传入参数cmp制定自定义的排序方式
    while (!pq.empty())
    {
    
    
        cout << pq.top() << " ";
        pq.pop();
    }
    return 0;
}

Parmi eux, cmp peut également être créé avec le mot-clé struct :

struct cmp{
    
    
 //重载()运算符
 bool operater()(T a,T b){
    
    
    return a > b;
 }
}

L'implémentation sous-jacente de std::less et std::greater :


// std::less<T> 的底层实现代码
template <typename T>
struct less {
    
    
    //定义新的排序规则
    bool operator()(const T &_lhs, const T &_rhs) const {
    
    
        return _lhs < _rhs;
    }
};
 
// std::greater<T> 的底层实现代码
template <typename T>
struct greater {
    
    
    bool operator()(const T &_lhs, const T &_rhs) const {
    
    
        return _lhs > _rhs;
    }

Guess you like

Origin blog.csdn.net/qq_43679351/article/details/124825229