Informatik

Warteschlange (Queue): FIFO einfach erklärt

Warteschlange (Queue): FIFO einfach erklärt
Warteschlange (Queue): FIFO einfach erklärt
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Eine Warteschlange, auf Englisch Queue, speichert Elemente in ihrer Ankunftsreihenfolge: Was zuerst hineinkommt, kommt zuerst wieder heraus. Dieses Prinzip heißt FIFO (First In – First Out).

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Warum eine Queue nach FIFO arbeitet

Stell dir eine Warteschlange an einer Kasse vor. Eine Person stellt sich hinten an. Bedient wird die Person, die vorne schon am längsten wartet. Genau diese Ordnung bildet eine Queue ab.

Definition

FIFO

First In – First Out bedeutet: Von allen noch gespeicherten Elementen wird das zuerst eingefügte Element auch zuerst entfernt.

Eine Queue hat deshalb zwei verschiedene Enden:

  • vorne (front): Hier liegt das älteste vorhandene Element und wird entnommen.
  • hinten (rear oder tail): Hier werden neue Elemente angefügt.
Beispiel

Du fügst nacheinander A, B und C ein. Die Queue sieht dann von vorne nach hinten so aus:

vorne → A | B | C ← hinten

A kam zuerst an. Deshalb wird A auch zuerst entfernt.

Merke

Eine Queue sortiert ihre Elemente nicht neu. Sie bewahrt die Einreihungsfolge.

Teste dich
Frage 1 von 1LeichtIn einer Queue stehen von vorne nach hinten Mia | Ben | Eda. Welches Element verlässt sie als Nächstes?
Lösung: MiaMia wurde von den noch vorhandenen Elementen zuerst eingereiht und steht deshalb vorne.
Was die vier Grundoperationen tun

Die Queue wird durch ihre erlaubten Operationen beschrieben. Wie sie intern gespeichert ist, spielt für diese Bedeutung zunächst keine Rolle.

Definition

Grundoperationen

  • enqueue(x) fügt das Element x hinten an.
  • dequeue() gibt das Element vorne zurück und entfernt es.
  • front() liest das Element vorne, entfernt es aber nicht.
  • empty() prüft, ob kein Element gespeichert ist.

Die Namen können in Programmiersprachen abweichen. Eine Bibliothek kann etwa push statt enqueue und pop statt dequeue verwenden. Entscheidend ist die Wirkung der Operation.

Beispiel

Ausgangszustand: vorne → Herz Dame | Karo König | Kreuz Ass ← hinten

  1. front() liefert Herz Dame. Die Queue bleibt unverändert.
  2. dequeue() liefert und entfernt Herz Dame.
  3. Danach liegt Karo König vorne.

Der Unterschied ist wichtig: front() schaut nur nach, dequeue() schaut nach und entfernt.

Was passiert bei einer leeren Queue?

Vor front() oder dequeue() solltest du mit empty() prüfen, ob ein Element vorhanden ist. Auf einer leeren Queue gibt es kein vorderstes Element. Wie ein Programm diesen Fall meldet, muss die konkrete Implementierung festlegen.

Gut zu wissen

Der Versuch, aus einer leeren Queue zu entnehmen, wird Underflow genannt. Eine robuste Implementierung behandelt diesen Randfall ausdrücklich, statt so zu tun, als gäbe es ein Element.

Teste dich
Frage 1 von 1MittelDie Queue enthält 4 | 9. Welche Aussage über front() ist richtig?
Lösung: front() liefert 4, und die Queue enthält danach weiterhin 4 | 9. — Vorne steht das älteste Element 4. front() liest es, ohne den Zustand zu verändern.
Wie du Befehlsfolgen sicher simulierst

Notiere nach jeder Operation den vollständigen Zustand von vorne nach hinten. So überspringst du keinen Schritt und verwechselst die beiden Enden nicht.

Beispiel

Die Queue ist anfangs leer. Werte die Folge aus:

  1. enqueue(7)vorne → 7 ← hinten
  2. enqueue(12)vorne → 7 | 12 ← hinten
  3. enqueue(4)vorne → 7 | 12 | 4 ← hinten
  4. dequeue() liefert 7vorne → 12 | 4 ← hinten
  5. front() liefert 12 → die Queue bleibt vorne → 12 | 4 ← hinten
  6. enqueue(2)vorne → 12 | 4 | 2 ← hinten
  7. dequeue() liefert 12vorne → 4 | 2 ← hinten

Die ausgegebenen Werte sind zuerst 7, dann 12. Am Ende enthält die Queue von vorne nach hinten 4 | 2.

Lückentext

Wähle in jeder Lücke die passende Form und prüfe anschließend deine Antworten.

Bei enqueue kommt ein neues Element am hinzu. dequeue entfernt das vorhandene Element am Anfang. front liest dieses Element, es zu entfernen.

Lösungen: Lücke 1: Ende; Lücke 2: älteste; Lücke 3: ohne. Verfolge immer die Ankunftsreihenfolge: hinten anfügen, vorne lesen oder entnehmen.
Teste dich
Frage 1 von 2MittelEine leere Queue erhält nacheinander enqueue(A), enqueue(B), dequeue(), enqueue(C). Welcher Zustand bleibt von vorne nach hinten?
Lösung: B | C — Nach den ersten beiden Schritten steht A | B. Dann wird A entfernt und C hinten an B angefügt.
Frage 2 von 2SchwerEine Queue enthält P | Q | R. Nach genau einer Operation enthält sie Q | R. Welche Operation passt?
Lösung: dequeue() — Nur dequeue() entfernt das vorderste Element P.
Wie eine Queue intern gespeichert werden kann

Eine Queue ist ein abstrakter Datentyp: Ihre Operationen und deren Wirkung sind festgelegt, nicht aber eine einzige Speicherform. Deshalb können verschiedene Implementierungen nach außen dasselbe Queue-Verhalten zeigen.

ImplementierungGrundideeWichtige Besonderheit
ArrayElemente liegen in Feldern eines Arrays.Bei fester Größe ist die Kapazität begrenzt.
RingpufferEin- und Ausgabezeiger laufen zyklisch durch ein Array.Freie Plätze am Anfang werden nach dem Umlauf wieder genutzt.
Einfach verkettete ListeJeder Knoten verweist auf seinen Nachfolger; Zeiger markieren Anfang und Ende.Neue Knoten können am Ende angehängt und alte am Anfang entfernt werden.
Doppelt verkettete Liste mit WächternKnoten verweisen in beide Richtungen; Wächter begrenzen Anfang und Ende.Beim Ändern müssen die Verweise der beteiligten Nachbarn passend gesetzt werden.

Verkettete Queue

Bei einer einfach verketteten Queue zeigt head auf den vordersten und tail auf den hintersten Knoten.

  • enqueue(x): Der bisher letzte Knoten verweist auf den neuen Knoten; anschließend wird tail auf ihn gesetzt.
  • dequeue(): head wird auf den Nachfolger des bisherigen ersten Knotens gesetzt; der entfernte Speicher wird freigegeben.
  • Beim ersten Element zeigen head und tail auf denselben Knoten.
  • Wird dieses einzige Element entfernt, muss die Queue danach wieder eindeutig leer sein; beide Zeiger werden entsprechend zurückgesetzt.
Merke

Die Implementierung darf verschieden sein. Nach außen muss trotzdem gelten: hinten einfügen, vorne entnehmen, FIFO-Reihenfolge bewahren.

Teste dich
Frage 1 von 1MittelEine nicht leere, einfach verkettete Queue erhält ein neues Element. Welche Referenz muss danach auf den neuen letzten Knoten zeigen?
Lösung: tail — Nach dem Anhängen wird tail weitergesetzt, damit es wieder den letzten Knoten markiert.
Was leer und voll bei Implementierungen bedeutet

Leer und voll sind nicht dasselbe Problem:

  • Leer: Es ist kein Element zum Lesen oder Entfernen vorhanden. Das kann bei jeder Queue auftreten.
  • Voll: Es gibt in einer kapazitätsbegrenzten Implementierung keinen freien Speicherplatz für ein weiteres Element.
Definition

Overflow

Overflow bedeutet hier: Ein Element soll eingefügt werden, obwohl die feste Kapazität bereits ausgeschöpft ist.

Ein Ringpuffer braucht für diesen Fall eine festgelegte Strategie. Die Implementierung kann den Überlauf melden, zusätzlichen Speicher bereitstellen oder – wenn der Anwendungsfall das ausdrücklich erlaubt – das älteste Element überschreiben. Beim Überschreiben gehen alte Daten verloren.

Eine verkettete Queue hat dagegen nicht dieselbe feste Arraygrenze. Auch sie ist in einem realen Rechner nicht grenzenlos: Neue Knoten benötigen verfügbaren Speicher. Das ist jedoch ein anderer Grenzfall als ein Ringpuffer mit vorab festgelegter Kapazität.

Beispiel

Ein Ringpuffer fasst drei Elemente und enthält A | B | C. Nun soll D eingefügt werden.

  • Bei der Strategie Überlauf melden bleibt A | B | C erhalten, und das Einfügen scheitert kontrolliert.
  • Bei der Strategie ältestes Element überschreiben geht A verloren; die logische FIFO-Reihenfolge der verbleibenden Elemente ist danach B | C | D.

Welche Reaktion richtig ist, hängt vom festgelegten Anwendungsfall ab. Sie darf nicht zufällig entstehen.

Teste dich
Frage 1 von 2MittelEin Ringpuffer mit Kapazität 3 enthält bereits drei Elemente. Was muss vor dem nächsten enqueue geklärt sein?
Lösung: Wie die Implementierung den Overflow behandelt. — Bei fester, ausgeschöpfter Kapazität braucht enqueue eine festgelegte Überlaufstrategie.
Frage 2 von 2SchwerZwei Programme bieten dieselben Queue-Operationen. Eines nutzt einen Ringpuffer, das andere eine verkettete Liste. Welche Aussage trifft zu?
Lösung: Beide können nach außen dasselbe FIFO-Verhalten haben, obwohl sie Elemente intern anders speichern. — Der abstrakte Datentyp legt die sichtbare Wirkung fest; die interne Datenstruktur kann unterschiedlich sein.
Queue oder Stack – welche Reihenfolge brauchst du?

Eine Queue wird leicht mit einem Stack verwechselt. Beim Stack wird das zuletzt abgelegte Element zuerst entnommen: LIFO (Last In – First Out).

FrageQueueStack
Welche Reihenfolge gilt?FIFOLIFO
Wo wird eingefügt?hintenam selben zugänglichen Ende
Was wird als Nächstes entnommen?das älteste vorhandene Elementdas zuletzt abgelegte Element
Beispiel

Du speicherst nacheinander 1, 2, 3.

  • Queue: Die erste Entnahme liefert 1.
  • Stack: Die erste Entnahme liefert 3.

Die Eingabefolge ist gleich, aber die Entnahmeregel ist verschieden.

Queues passen beispielsweise zu Druckaufträgen oder gepufferten Eingaben, wenn die Ankunftsreihenfolge erhalten bleiben soll. Sie entkoppeln das Einstellen eines Auftrags von seiner späteren Verarbeitung.

Teste dich
Frage 1 von 1SchwerDrei Druckaufträge X, Y, Z kommen in dieser Reihenfolge an und sollen ohne Priorisierung in Ankunftsreihenfolge verarbeitet werden. Welche Struktur passt?
Lösung: Eine Queue, weil X als ältester Auftrag zuerst entnommen wird. — Die Anforderung „in Ankunftsreihenfolge“ entspricht direkt dem FIFO-Prinzip einer Queue.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Warteschlange (Queue)
    • FIFO: ältestes vorhandenes Element zuerst
    • Operationen: enqueue, dequeue, front, empty
    • Randfälle: leer, ein Element, volle feste Kapazität
    • Implementierungen: Array, Ringpuffer, verkettete Liste
    • Abgrenzung: Queue FIFO, Stack LIFO
    • Anwendungen: Aufträge und Eingaben puffern
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWelche Operation liest das vorderste Element, ohne die Queue zu verändern?
Lösung: front()front() liest nur. enqueue fügt hinzu und dequeue entfernt.
Frage 2 von 3MittelEine leere Queue führt enqueue(5), enqueue(8), dequeue(), enqueue(3), front() aus. Was liefert front(), und wie lautet der Endzustand?
Lösung: front() liefert 8; der Endzustand ist 8 | 3. — Nach dem Entfernen von 5 steht 8 vorne. 3 kommt hinten hinzu, und front() entfernt 8 nicht.
Frage 3 von 3SchwerEine Queue-Implementierung entfernt beim letzten dequeue() ihr einziges Element. Welche Bedingung muss anschließend gelten?
Lösung: Die Queue ist leer, und ein späteres front() darf nicht so behandelt werden, als gäbe es noch ein Element. — Der Ein-Element-Fall muss den leeren Zustand korrekt herstellen; die FIFO-Regel ändert sich dabei nicht.

Passend dazu