Menu
Coddy logo textTech

Queue (Warteschlange)

Zuletzt aktualisiert

Eine Queue hat zwei aktive Enden. Neue Werte reihen sich hinten ein, entnommen wird vorne, sodass immer der Wert zuerst drankommt, der am längsten gewartet hat. Das ist FIFO, und genau so verhält sich eine Schlange an der Kasse: Hinten anstellen und vorne bedient werden ist das, was das Warten fair macht. Drücke oben auf Abspielen und sieh zu, wie Werte auf der einen Seite hineingehen und auf der anderen wieder heraus.

Weil jedes Ende seinen eigenen Index oder Zeiger hat, kosten beide Operationen O(1), und keine von beiden verschiebt die übrigen Daten. Deshalb steckt eine Queue unter allem, was Arbeit in der Reihenfolge ihres Eintreffens abarbeitet: Druckaufträge, Task- und Message-Queues, Anfragepuffer und die Breitensuche, die einen Graphen genau deshalb Ebene für Ebene besucht, weil sie ihre Front in einer Queue hält. Verschiebe das Ende, an dem entfernt wird, nach hinten, und du hast stattdessen einen Stack.

Zeit- und Speicherkomplexität

Für eine Queue auf Basis eines Ringpuffers oder einer verketteten Liste, die beiden üblichen Implementierungen:

OperationKomplexitätHinweise
Enqueue (einreihen)O(1)Hinten schreiben und den hinteren Index weiterrücken.
Dequeue (entnehmen)O(1)Vorne lesen und den vorderen Index weiterrücken, ohne etwas zu verschieben.
Peek (vorne ansehen)O(1)Den vordersten Wert lesen, ohne ihn zu entfernen.
SuchenO(n)Dafür ist eine Queue nicht gedacht: Du musst sie leeren, um hineinzusehen.
SpeicherO(n)Ein Platz pro wartendem Wert.

Schritt für Schritt

SchrittWas passiert
1Die Queue startet leer, vorne und hinten zeigen auf denselben Platz.
2Enqueue schreibt den Wert hinten und rückt das hintere Ende danach um eins weiter.
3Jedes weitere Enqueue landet hinter den Werten, die schon warten.
4Dequeue liest den Wert vorne und rückt das vordere Ende danach um eins weiter.
5Zurück kommt immer der Wert, der am längsten gewartet hat.
6Treffen vorne und hinten aufeinander, ist die Queue wieder leer, und ein weiteres Dequeue ist ein Fehler.

Durchgerechnetes Beispiel

3, 7 und 5 einreihen und die Queue danach leeren:

OperationQueue (vorne nach hinten)Gibt zurück
enqueue(3)[3]nichts
enqueue(7)[3, 7]nichts
enqueue(5)[3, 7, 5]nichts
dequeue()[7, 5]3, der älteste Wert
dequeue()[5]7
dequeue()[]5, der neueste Wert, zuletzt

Wann man eine Queue verwendet

Verwenden, wennVermeiden, wenn
Arbeit in der Reihenfolge ihres Eintreffens erledigt werden muss: Job-Queues, Anfragepuffer, DruckerspoolerDu das zuletzt hinzugefügte Element zuerst brauchst, dafür ist ein Stack da
Du Ebene für Ebene erkundest, so wie es die Breitensuche tutElemente nach Priorität statt nach Eintreffen bedient werden müssen, wofür ein Heap passt
Ein Producer und ein Consumer unterschiedlich schnell laufen und einen Puffer dazwischen brauchenDu in der Mitte der Daten suchen oder indizieren musst
Du O(1) beim Einfügen und Entfernen willst, ohne Elemente zu verschiebenDu sie umsetzen würdest, indem du bei jedem Dequeue ein Array verschiebst, was sie O(n) macht

Queue-Code

Eine saubere, lauffähige Queue-Implementierung in Python, JavaScript, Java, C++, C. Wähle eine Sprache, kopiere den Code oder öffne ihn vorgeladen im Coddy-Playground.

Queue-Code in Python

Python
1from collections import deque2
3queue = deque()4
5# Enqueue three values at the rear6for value in [3, 7, 5]:7    queue.append(value)8    print(f"enqueue {value} -> {list(queue)}")9
10# Dequeue them from the front: first in, first out11while queue:12    value = queue.popleft()13    print(f"dequeue {value} -> {list(queue)}")14
15print("empty:", len(queue) == 0)
Führe diesen Code im Python-Playground aus

Queue FAQ

Was bedeutet FIFO?
First in, first out: Der Wert, der am längsten gewartet hat, ist der nächste, der bedient wird. Das alltägliche Bild ist die Schlange am Ticketschalter. Ein Stack folgt der umgekehrten Regel, LIFO.
Was ist der Unterschied zwischen einer Queue und einem Stack?
Nur das Ende, an dem entfernt wird. Beide fügen hinten in O(1) hinzu; eine Queue entfernt vorne (FIFO), ein Stack an demselben Ende, an dem er hinzugefügt hat (LIFO). Ihre Komplexitätstabellen sind ansonsten identisch.
Was sind die wichtigsten Queue-Operationen?
enqueue hängt einen Wert hinten an, dequeue entfernt den vordersten Wert und gibt ihn zurück, peek (oder front) liest den vordersten Wert, ohne ihn zu entfernen, und is_empty meldet, ob noch etwas wartet. Alle vier sind O(1).
Warum ist dequeue langsam, wenn ich ein einfaches Array verwende?
Weil das Entfernen von Index 0 aus einem Array jedes verbleibende Element nach links verschiebt, was jedes Dequeue O(n) macht. Echte Implementierungen vermeiden das mit einem Ringpuffer, der einen vorderen Index weiterrückt, oder mit einer verketteten Liste mit Kopfzeiger. Pythons collections.deque und Javas ArrayDeque erledigen das für dich, list.pop(0) nicht.
Was ist eine zirkuläre Queue?
Eine Queue in einem Array fester Größe, in dem der vordere und der hintere Index wieder auf 0 springen, sobald sie hinten hinauslaufen. Sie nutzt die Plätze wieder, die Dequeues frei gemacht haben, sodass eine Queue mit der Kapazität n unbegrenzt weiterarbeitet, statt am Ende des Arrays anzustoßen.
Wo werden Queues in echten Programmen eingesetzt?
Task- und Message-Queues zwischen Diensten, Druck- und Job-Spooler, Anfragepuffer in Webservern, Tastatur- und Ereignispuffer, Producer-Consumer-Pipelines und die Breitensuche, bei der die Queue dafür sorgt, dass der Durchlauf Ebene für Ebene abläuft.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S