Puisque les seules opérations requises pour qu'un conteneur soit utilisé dans une pile sont:
- arrière()
- repousser()
- pop_back ()
Pourquoi le conteneur par défaut est-il un deque au lieu d'un vecteur?
Les réallocations deque ne donnent-elles pas un tampon d'éléments avant front () pour que push_front () soit une opération efficace? Ces éléments ne sont-ils pas gaspillés puisqu'ils ne seront jamais utilisés dans le contexte d'une pile?
S'il n'y a pas de surcharge pour utiliser un deque de cette façon au lieu d'un vecteur, pourquoi la valeur par défaut pour priority_queue est-elle un vecteur pas également un deque? (priority_queue nécessite front (), push_back () et pop_back () - essentiellement les mêmes que pour stack)
Mis à jour en fonction des réponses ci-dessous:
Il semble que la façon dont deque est généralement implémentée est un tableau de taille variable de tableaux de taille fixe. Cela rend la croissance plus rapide qu'un vecteur (qui nécessite une réallocation et une copie), donc pour quelque chose comme une pile qui consiste à ajouter et supprimer des éléments, deque est probablement un meilleur choix.
priority_queue nécessite une indexation importante, car chaque suppression et insertion vous oblige à exécuter pop_heap () ou push_heap (). Cela fait probablement du vecteur un meilleur choix, car l'ajout d'un élément est toujours amorti constant de toute façon.
la source
Réponses:
Au fur et à mesure que le conteneur grandit, une réallocation pour un vecteur nécessite de copier tous les éléments dans le nouveau bloc de mémoire. La croissance d'un deque alloue un nouveau bloc et le lie à la liste des blocs - aucune copie n'est requise.
Bien sûr, vous pouvez spécifier qu'un conteneur de support différent soit utilisé si vous le souhaitez. Donc, si vous avez une pile dont vous savez qu'elle ne va pas grandir beaucoup, dites-lui d'utiliser un vecteur au lieu d'un deque si c'est votre préférence.
la source
std::deque
qu'elle ne l'est pourstd::vector
, et ces opérations sont susceptibles d'être utilisées beaucoup plus fréquemment que les réallocations. J'ai du mal à croire questd::deque
cela battrait un jourstd::vector
en pratique.list
, pourquoideque
?std::deque
avoir une chance de battrestd::vector
dans la pratique, ou voulez-vous dire que vous en doutez encore? Merci.std::deque
cela fonctionnera aussi bien questd::vector
dans les applications pratiques. Mais pour ce que cela vaut, mon expérience personnelle est que j'ai besoin de structures de données de pile et de file d'attente non pas pour une tâche importante et cruciale, mais pour de nombreuses petites occasions parsemées dans mon code. En tant que tel, je me soucie plus du comportement des petits que des grands; et deque y brille particulièrement terne. Ma préférence est de n'utiliser ni l'un ni l'autre, mais (auto-implémenté) des listes liées individuellement. Mais votre kilométrage peut varier.Voir le gourou de la semaine 54 de Herb Sutter de pour les mérites relatifs du vecteur et de quel domaine ferait l'un ou l'autre.
J'imagine que l'incohérence entre priority_queue et queue est simplement que différentes personnes les ont implémentées.
la source
priority_queue
doit rester trié, de sorte que la surcharge plus élevée de l'accès aléatoiredeque::iterator
est plus problématique.priority_queue
a un "ordre magique" qui est maintenu, il n'est pas trié. Cependant, votre argument est valable.