Da die einzigen Operationen, die erforderlich sind, damit ein Container in einem Stapel verwendet werden kann, folgende sind:
- zurück()
- push_back ()
- Pop zurück()
Warum ist der Standardcontainer dafür eine Deque anstelle eines Vektors?
Geben Deque-Neuzuweisungen nicht einen Puffer mit Elementen vor front () an, sodass push_front () eine effiziente Operation ist? Werden diese Elemente nicht verschwendet, da sie niemals im Kontext eines Stapels verwendet werden?
Wenn es keinen Overhead für die Verwendung einer Deque auf diese Weise anstelle eines Vektors gibt, warum ist die Standardeinstellung für priority_queue ein Vektor und keine Deque? (priority_queue erfordert front (), push_back () und pop_back () - im Wesentlichen dasselbe wie für stack)
Aktualisiert basierend auf den folgenden Antworten:
Es scheint, dass die Art und Weise, wie deque normalerweise implementiert wird, ein Array variabler Größe von Arrays fester Größe ist. Dies macht das Wachstum schneller als ein Vektor (der eine Neuzuweisung und ein Kopieren erfordert). Für so etwas wie einen Stapel, bei dem es nur um das Hinzufügen und Entfernen von Elementen geht, ist deque wahrscheinlich die bessere Wahl.
priority_queue erfordert eine starke Indizierung, da Sie bei jedem Entfernen und Einfügen pop_heap () oder push_heap () ausführen müssen. Dies macht den Vektor dort wahrscheinlich zu einer besseren Wahl, da das Hinzufügen eines Elements sowieso immer noch konstant abgeschrieben wird.
quelle
Antworten:
Wenn der Container wächst, müssen für eine Neuzuweisung eines Vektors alle Elemente in den neuen Speicherblock kopiert werden. Wenn Sie eine Deque vergrößern, wird ein neuer Block zugewiesen und mit der Liste der Blöcke verknüpft. Es sind keine Kopien erforderlich.
Natürlich können Sie festlegen, dass ein anderer Hintergrundcontainer verwendet werden soll, wenn Sie möchten. Wenn Sie also einen Stapel haben, von dem Sie wissen, dass er nicht viel wachsen wird, sagen Sie ihm, dass er einen Vektor anstelle einer Deque verwenden soll, wenn Sie dies bevorzugen.
quelle
std::deque
als fürstd::vector
, und diese Operationen werden wahrscheinlich viel häufiger verwendet als Neuzuweisungen. Es fällt mir schwer zu glauben, dassstd::deque
dasstd::vector
in der Praxis jemals schlagen würde .list
, warumdeque
?std::deque
du eine Chancestd::vector
hast, in der Praxis zu schlagen , oder meinst du, du zweifelst immer noch daran? Vielen Dank.std::deque
dies genauso gut funktioniert wiestd::vector
in praktischen Anwendungen. Meine persönliche Erfahrung ist jedoch, dass ich Stapel- und Warteschlangendatenstrukturen nicht für eine große und komplexitätskritische Aufgabe benötige, sondern für viele kleine Gelegenheiten, die durch meinen Code gestreut werden. Als solches interessiert mich das Verhalten im Kleinen mehr als im Großen; und deque leuchtet dort besonders langweilig. Ich bevorzuge es, stattdessen keine, sondern (selbst implementierte) einfach verknüpfte Listen zu verwenden. Ihr Kilometerstand kann jedoch variieren.Siehe Herb Sutters Guru der Woche 54 für die relativen Vorzüge von Vektor und Deque, wo beides tun würde.
Ich stelle mir vor, dass die Inkonsistenz zwischen priority_queue und queue einfach darin besteht, dass verschiedene Personen sie implementiert haben.
quelle
priority_queue
muss bleiben sortiert, damit der höhere Aufwand für zufällig Zugriff aufdeque::iterator
mehr problematisch ist.priority_queue
hat eine "magische Ordnung", die beibehalten wird, es ist nicht sortiert. Ihr Punkt steht jedoch.