Deque

Ein Deque (Double-ended queue, sprich: „Deck“) bezeichnet eine Datenstruktur der Informatik.

Hierbei handelt es sich um eine Datenstruktur ähnlich der Warteschlange oder des Stapelspeichers. Es kombiniert die Eigenschaften beider Datentypen. Der Unterschied besteht darin, dass die Daten an beiden Enden gelesen, eingefügt oder entfernt werden können.

Eigenschaften

Die Operationen eines Deque, die in den Programmbibliotheken verschiedener Programmiersprachen nicht einheitlich benannt sind:

  • push und pop für das Einfügen oder Entnehmen eines Elements am hinteren Ende der Deque.
  • put und get für das Einfügen oder Entnehmen am vorderen Ende der Deque.
  • first und last für das Lesen des ersten oder letzten Elementes, ohne es zu entfernen.

Technisch wird ein Deque entweder als doppelt verkettete Liste realisiert – also ähnlich wie bei der Warteschlange oder dem Stapelspeicher – oder als Feld mit Hilfsindizes.

Deques sind Sequenzcontainer mit dynamischen Größen, die an beiden Enden (entweder vorne oder hinten) erweitert oder verkleinert werden können. Bestimmte Programmbibliotheken können Deques auf unterschiedliche Weise implementieren, im Allgemeinen als eine Form eines dynamischen Arrays. In jedem Fall ermöglichen sie jedoch den direkten Zugriff auf die einzelnen Elemente über Iteratoren mit wahlfreiem Zugriff, wobei der Speicher automatisch verwaltet wird, indem der Container nach Bedarf erweitert und verkleinert wird.

Daher bieten sie eine ähnliche Funktionalität wie Arrays, jedoch mit effizienter Einfügung und Löschung von Elementen auch am Anfang der Sequenz und nicht nur am Ende. Im Gegensatz zu Arrays wird jedoch nicht garantiert, dass Deques alle ihre Elemente an zusammenhängenden Speicheradressen speichern: Der Zugriff auf Elemente in einer Deque durch Versetzen eines Zeigers auf ein anderes Element führt zu undefiniertem Verhalten. Sowohl dynamischen Arrays als auch Deques bieten eine sehr ähnliche Schnittstelle und können für ähnliche Zwecke verwendet werden, aber intern funktionieren beide auf ganz unterschiedliche Weise: Während Vektoren ein einzelnes Array verwenden, das gelegentlich für das Wachstum neu zugewiesen werden muss, können die Elemente eines Deque auf verschiedene Speicherblöcke verstreut werden, wobei der Container die erforderlichen Informationen intern speichert, um in konstanter Laufzeit und mit einer einheitlichen sequentiellen Schnittstelle (über Iteratoren) direkten Zugriff auf eines seiner Elemente zu ermöglichen.

Daher sind Deques intern etwas komplexer, aber dies ermöglicht es ihnen, unter bestimmten Umständen effizienter zu wachsen, insbesondere bei sehr langen Sequenzen, bei denen Neuzuweisungen teurer werden. Bei Operationen, bei denen Elemente häufig an anderen Positionen als am Anfang oder am Ende eingefügt oder entfernt werden, sind Deques schlechter und weisen weniger konsistente Iteratoren und Referenzen auf als Listen.[1]

In der Praxis verwendet man die Deque unter anderem zur Implementierung von nichtdeterministischen endlichen Automaten und zur Textsuche mittels regulärer Ausdrücke (Pattern-Matching-Algorithmus).

Programmierung

Das folgende Beispiel in der Programmiersprache C++ mit Spielkarten zeigt die Verwendung der Klasse deque der C++-Standardbibliothek (siehe auch Template (C++) - Klassen-Templates). Bei der Ausführung des Programms wird die Methode main verwendet.[2]

#include <deque> // Bindet den Datentyp deque in das Programm ein
#include <iostream>

using namespace std;

int main()
{
    deque<string> myDeque; // Deklariert ein Deque mit dem Elementtyp string

    // Fügt dem Deque 3 Elemente vom Typ string am Ende hinzu
    myDeque.push_back("Kreuz Bube");
    myDeque.push_back("Herz Dame");
    myDeque.push_back("Karo König");

    int n = myDeque.size(); // Weist die Anzahl der Elemente der Variablen n zu
    cout << "Die Länge des Deque ist "
         << n << endl; // Ausgabe auf der Konsole
    string card = myDeque.front(); // Weist das Element am Anfang ("Kreuz Bube") der Variablen card zu
    cout << "Die Karte am Anfang der Deque ist: "
         << card << endl; // Ausgabe auf der Konsole
    card = myDeque.back(); // Weist das Element am Ende ("Karo König") der Variablen card zu
    cout << "Die Karte am Ende der Deque ist: "
         << card << endl; // Ausgabe auf der Konsole
    cout << toString(myDeque) << endl; // Ausgabe auf der Konsole: (Kreuz Bube, Herz Dame, Karo König)

    myDeque.push_front("Kreuz 10"); // Fügt 1 Element am Anfang des Deque ein

    n = myDeque.size(); // Weist die Anzahl der Elemente der Variablen n zu
    cout << "Die Länge des Deque ist "
         << n << endl; // Ausgabe auf der Konsole
    cout << toString(myDeque) << endl; // Ausgabe auf der Konsole: (Kreuz 10, Kreuz Bube, Herz Dame, Karo König)

    myDeque.pop_back(); // Entfernt das Element am Ende
    cout << toString(myDeque) << endl; // Ausgabe auf der Konsole: (Kreuz 10, Kreuz Bube, Herz Dame)

    myDeque.push_back("Karo Ass"); // Fügt dem Deque 1 Element am Ende hinzu
    cout << toString(myDeque) << endl; // Ausgabe auf der Konsole: (Kreuz 10, Kreuz Bube, Herz Dame, Karo Ass)

    myDeque.pop_front(); // Entfernt das Element am Anfang
    cout << toString(myDeque) << endl; // Ausgabe auf der Konsole: (Kreuz Bube, Herz Dame, Karo Ass)
}

Für die Ausgabe des Deque wird folgende Methode verwendet:

// Diese Methode gibt das Deque in der Form (A, B, C, ...) als Text zurück.
string toString(deque<string> aDeque)
{
    string text = "(";
    for (int i = 0; i < aDeque.size() - 1; i++) // for-Schleife
    {
        text += aDeque.at(i) + ", "; // Greift auf das Element mit dem Index i zu
    }
    text += aDeque.at(aDeque.size() - 1) + ")";
    return text;
}

Für die Programmierung von Kartenspielen und Gesellschaftsspielen mit Stapeln, bei denen während dem Spiel Karten auf einen Stapel gelegt oder von einem Stapel gezogen wird, sind stattdessen Stacks geeignet (siehe Stapelspeicher - Beispiel mit Spielkarten).

Siehe auch

Weblinks

www.geeksforgeeks.org: Implementation of Deque using doubly linked list

Einzelnachweise

  1. www.cplusplus.com: deque
  2. Microsoft Docs: deque Class