Wird geladen...

Sequenzielle Datenstrukturen mit std::list und std::deque in C++

Lernen Sie std::list und std::deque in C++ kennen, einschließlich Leistungsunterschieden und typischen Einsatzgebieten.

In C++ sind std::list und std::deque sequentielle Datenstrukturen, die in Situationen eingesetzt werden, in denen std::vector nicht ideal ist. std::list implementiert eine doppelt verkettete Liste, während std::deque (double-ended queue) schnelle Einfügungen und Löschungen an beiden Enden ermöglicht. Dieser Artikel erklärt, wann welche Struktur sinnvoll ist und zeigt praxisnahe Beispiele.


1) Was ist std::list?

std::list ist eine doppelt verkettete Liste:


#include <list>
#include <iostream>
using namespace std;

int main() {
    list<int> lst = {10, 20, 30};

    lst.push_front(5);   // vorne einfügen
    lst.push_back(40);   // hinten einfügen

    auto it = lst.begin();
    advance(it, 2);      // 2 Schritte vorwärts
    lst.insert(it, 25);  // in der Mitte einfügen

    for (int x : lst) cout << x << " ";
}

Einsatzgebiet: Wenn häufig Einfügungen oder Löschungen in der Mitte erfolgen.


2) Leistungsmerkmale von std::list


// sortieren einer Liste
list<int> lst = {5, 2, 9, 1};
lst.sort();

3) Was ist std::deque?

std::deque ist eine doppelseitige Warteschlange (Double-Ended Queue), die schnelle Operationen an beiden Enden ermöglicht.


#include <deque>
#include <iostream>
using namespace std;

int main() {
    deque<int> dq = {10, 20, 30};

    dq.push_front(5);
    dq.push_back(40);

    dq.pop_front();
    dq.pop_back();

    cout << dq[0] << endl;  // Random Access möglich
}

Einsatzgebiet: Wenn schnelle Operationen an beiden Enden benötigt werden.


4) Leistungsmerkmale von std::deque


5) Vergleich: list vs deque

Eigenschaftlistdeque
Zufälliger Zugriff Nein Ja (O(1))
Schnelles Einfügen vorne O(1) O(1)
Schnelles Einfügen hinten O(1) O(1)
Einfügen in der Mitte O(1) O(n)
Speicherstruktur Verteilte Knoten Segmentierte Blöcke
Empfohlen bei Häufige Einfügungen/Entfernungen in der Mitte Schnelle Operationen an beiden Enden

6) Praxisbeispiele: Warteschlange & Entity-Verwaltung

a) Task-Warteschlange mit deque


#include <deque>
#include <iostream>
using namespace std;

int main() {
    deque<string> tasks;

    tasks.push_back("Download");
    tasks.push_back("Parse");
    tasks.push_front("Init"); // priorisierte Aufgabe

    while (!tasks.empty()) {
        cout << "Aufgabe: " << tasks.front() << endl;
        tasks.pop_front();
    }
}

b) Entity-Verwaltung in einer Spiel-Engine mit list


#include <list>
#include <iostream>
using namespace std;

struct Entity {
    string name;
    Entity(string n) : name(n) {}
};

int main() {
    list<Entity> entities;

    entities.emplace_back("Player");
    entities.emplace_back("Enemy");
    entities.emplace_back("Tree");

    for (auto it = entities.begin(); it != entities.end(); ) {
        if (it->name == "Enemy")
            it = entities.erase(it);  // O(1)
        else
            ++it;
    }

    for (auto& e : entities)
        cout << e.name << endl;
}

7) Welche Struktur sollte man verwenden?

Grundregel: Zuerst vector ausprobieren. Wenn das nicht passt, deque oder list wählen.


8) TL;DR

  • list: doppelt verkettete Liste → O(1) Mitte-Operationen, kein Random Access.
  • deque: Double-Ended Queue → O(1) vorne/hinten, Random Access möglich.
  • deque nicht vollständig zusammenhängend; list benötigt mehr Speicher.
  • Profiling ist der beste Weg, reale Performance zu verstehen.
  • Alle Beispiele sind kompatibel mit Visual Studio 2022 und GCC 11+.

Ähnliche Artikel