web-dev-qa-db-fra.com

Y a-t-il des collections triées en C ++?

En SmallTalk, vous pouvez créer une triée, qui consiste à dire que vous pouvez ajouter un élément et cela l'insérerait dans le bon emplacement.

Y a-t-il quelque chose comme celui-ci en C++? Ou même mieux y a-t-il quelque chose comme un type de tri, tel que lorsque vous ajoutez un élément, il trierait-le dans une file d'attente comme une structure que vous pouvez simplement faire sortir le premier élément de?

J'ai examiné ensemble, c'est ce dont j'ai besoin en termes de tri, mais c'est une collection non ordonnée. Je cherche un petit temps de course aussi possible.

19
Jim

Vous semblez rechercher le std::priority_queue , situé dans le fichier d'en-tête <queue>. Avec Push(), vous pouvez insérer un élément dans la file d'attente de priorité; Avec top(), vous obtiendrez l'élément actuellement le plus important de la file d'attente (ou le plus petit, en fonction de la mise en œuvre operator<); et avec pop(), vous supprimerez l'élément le plus important/le plus petit.

Autant que je sache, il est mis en œuvre avec un tas, ce qui rend la complexité de chaque opération de poussée et pop O (LG N) . Il suffit de regarder l'élément supérieur est effectué dans O (1) .

20
Aasmund Eldhuset

Il existe quatre conteneurs triés dans la bibliothèque standard C++:

std::set - une séquence triée de valeurs uniques.
[.____] std::map - une séquence triée de paires de clé/valeur unique.
[.____] std::multiset - une séquence de valeurs triée (répétitions possibles).
[.____] std::multimap - une séquence triée de paires de clé/de valeur (répétitions possibles).

Si vous voulez juste une file d'attente triée, ce que vous recherchez est std::priority_queue , qui est un adaptateur de conteneur plutôt qu'un récipient autonome.

#include <queue>

int main()
{
    std::priority_queue<int> q;
    q.Push(2);
    q.Push(3);
    q.Push(1);
    assert(q.top() == 3); q.pop();
    assert(q.top() == 2); q.pop();
    assert(q.top() == 1); q.pop();
    return 0;
}

Si vous souhaitez stocker vos propres types dans un priority_queue alors vous devez définir operator< Pour votre classe.

class Person
{
public:
    Person(int age) : m_age(age) {}

    bool operator<(const Person& other) const
    {
        return m_age < other.m_age;
    }

private:
    int m_age;
};

Créer un priority_queue de Persons vous donnerait alors une file d'attente avec les personnes les plus anciennes à l'avant.

53
Peter Alexander

L'organigramme de choix de conteneur stl (de -- this question):

51
Igor Oks

std :: map pour le conteneur trié

STD :: Queue pour la file d'attente.

std :: priority_queue pour la queue triée

7
littleadv

std::set est une collection ordonnée; Itération sur elle vous donnera les éléments dans l'ordre (soit défini par le < opérateur ou prédicat personnalisé). Trouver et éliminer le premier élément sont O (1).

Sinon, vous pouvez utiliser std::priority_queue, qui est fondamentalement un tas et permet une élimination efficace de l'insertion et du moindre élément.

En fait, il est plus difficile de trouver des conteneurs non ordonnés (hachés) - ils n'étaient pas une partie de la norme d'origine, bien qu'ils soient largement disponibles sous forme non standard.

Bien sûr, vous constaterez peut-être que la simple tenue de vos articles dans un vecteur trié est plus rapide, même si elle est théoriquement plus lente, si le nombre d'articles n'est pas significativement important.

2
Alan Stokes