edubun
Deutsch

Warteschlangen (Queues)

Den ersten von 1000 Werten mit shift aus einem JavaScript-Array zu nehmen, verschiebt die anderen 999; ein Ringpuffer erledigt dieselbe Aufgabe in einem Schritt.

First in, first out

Eine Warteschlange ist wie die Schlange an einer Ladenkasse. Man stellt sich hinten an und wird vorn bedient, also geht als Erstes, wer zuerst kam. Die Regel heißt first in, first out (FIFO). Die beiden Operationen sind Einreihen (enqueue), das einen Wert hinten anfügt, und Entnehmen (dequeue), das den Wert vorn entfernt. In den Unterlagen von MIT 6.006 ist eine Warteschlange die Sequenz-Schnittstelle, beschränkt auf insert last(x) und delete first().

Warteschlangen gibt es überall, wo Arbeit in der Reihenfolge des Eintreffens erledigt werden muss: Dokumente, die auf einen Drucker warten, Tastendrücke, die auf ein Programm warten, Nachrichten, die auf einen Server warten. Die Breitensuche aus dem Algorithmenkurs hält die Felder, die sie noch besuchen muss, in einer Warteschlange, und genau deshalb erkundet sie in Ringen gleichen Abstands.

Der einfache Weg und seine versteckten Kosten

In JavaScript ist die naheliegende Warteschlange ein Array: push zum Einreihen hinten und shift zum Entnehmen vorn. Das funktioniert, und für kurze Warteschlangen ist es in Ordnung. Aber sieh dir an, was shift tut. MDN sagt, es verschiebe „alle Werte um 1 nach links“, und die ECMAScript-Spezifikation schreibt es als Schleife, die für jedes k das Element k an Position k − 1 kopiert. Der Anfang eines Arrays ist das teure Ende, wie die erste Einheit gezeigt hat. Das Entnehmen aus einer Warteschlange mit n Werten kostet 1 Lesevorgang plus n − 1 Verschiebungen, eine Warteschlange mit 1000 Werten kostet also 1000 Schritte pro Entnahme. (Engines nutzen intern vielleicht Abkürzungen, aber die Spezifikation verspricht keine.)

Reihst du 5 Werte in ein leeres Array ein und entnimmst dann alle 5, kosten die Einreihungen 5 Schritte und die Entnahmen 5 + 4 + 3 + 2 + 1 = 15, zusammen 20. Das meiste davon ist das Verschieben von Werten, die gar nicht entfernt werden.

Nicht die Werte bewegen, sondern den Anfang

Die Lösung: aufhören, Werte zu verschieben, und sich stattdessen merken, wo der Anfang ist. Führ einen Index namens head. Entnehmen liest den Wert bei head und erhöht head um 1; sonst bewegt sich nichts. Der Haken: Die Zellen vor head sind verschwendet. Ein Ringpuffer (zirkulärer Puffer) verwendet sie wieder: Das Array hat eine feste Zahl von Zellen, sagen wir 8, und die Positionen laufen im Kreis, die Zelle nach 7 ist also 0. Speichere head und size. Das nächste Einreihen geht in Zelle (head + size) mod 8, und ein Entnehmen nimmt Zelle head und setzt head auf (head + 1) mod 8. Beide Operationen kosten 1 Schritt. Der Preis ist eine feste Kapazität: Erreicht size den Wert 8, ist die Warteschlange voll, außer du kopierst alles in einen größeren Ring, wie es ein dynamisches Array tun würde.

Wird geladen

Zum Drehen ziehen. Zum Zoomen scrollen oder mit zwei Fingern ziehen.

Eine Warteschlange mit vier Werten. Bei „Array mit shift“ verschiebt jedes Entnehmen den Rest der Schlange. Stell die Art auf „Ringpuffer“ um, und die Werte bleiben, wo sie sind, während Anfang und Ende um den Ring wandern.
Probier das im Labor: Wechsle zum Ringpuffer, reih viermal ein, um alle 8 Zellen zu füllen, und reih noch einmal ein. Das Labor lehnt ab, weil ein fester Ring keine neunte Zelle hat. Entnimm dann zweimal und reih wieder ein: Der neue Wert kommt in Zelle 0, im Kreis herum.
Warteschlange mit n WertenEinreihenEntnehmen
Array mit push und shift1 (amortisiert)1 Lesevorgang + (n − 1) Verschiebungen
Array mit head-Index1 (amortisiert)1, aber vordere Zellen sind verschwendet
Ringpuffer fester Größe1, oder voll1

Was solltest du nehmen? Für eine Warteschlange, die nie mehr als ein paar Dutzend Werte enthält, ist push und shift kurz und klar, und das Verschieben kostet fast nichts. Für eine Warteschlange, durch die Tausende Elemente laufen, etwa die Felder einer großen Breitensuche, hält ein head-Index oder ein Ringpuffer jedes Entnehmen bei einem Schritt, und der Unterschied wächst mit der Länge der Schlange.

FIFOFirst in, first out: Werte gehen in der Reihenfolge, in der sie kamen.
Einreihen / EntnehmenHinten anfügen / vorn entfernen.
shiftEntfernt den ersten Array-Wert und schiebt alle anderen eine Zelle nach links.
RingpufferEin festes Array, im Kreis benutzt: Die nächste freie Zelle ist (head + size) mod Kapazität.
  1. In welcher Reihenfolge gibt eine Warteschlange Werte zurück?
    • First in, first out
    • Last in, first out
    • Das Größte zuerst
    • Zufällige Reihenfolge
  2. Reih A, B, C ein. Entnimm einmal. Reih D ein. Entnimm jetzt, bis die Schlange leer ist. Bring diese Werte in die richtige Reihenfolge.
  3. Wie viele Schritte kostet mit push und shift ein Entnehmen aus einer Warteschlange mit 4 Werten (1 Lesevorgang plus Verschiebungen)?
  4. Gleiches Verfahren, eine Warteschlange mit 1000 Werten: Wie viele Schritte für ein Entnehmen?
  5. Beginn mit einem leeren Array. Reih 5 Werte mit push ein und entnimm dann alle 5 mit shift. Wie viele Schritte insgesamt?
  6. Ein Ringpuffer hat 8 Zellen (0 bis 7), head = 6 und size = 3. Welche Zelle verwendet das nächste Einreihen?
  7. Wie viele Schritte kostet ein Entnehmen aus einem Ringpuffer, egal wie viele Werte er enthält?
  8. Ein fester Ring mit 8 Zellen enthält 8 Werte. Was passiert beim Einreihen?
    • Es überschreibt den vorderen Wert
    • Die Warteschlange ist voll, und der Wert wird abgelehnt
    • Es schiebt jeden Wert nach links
    • Es sortiert die Werte
  9. Welche Suche aus dem Algorithmenkurs hält ihre wartenden Felder in einer Warteschlange?
    • Binäre Suche
    • Breitensuche
    • Tiefensuche
    • Lineare Suche
  10. Welche zwei Sequenz-Operationen verwendet eine Warteschlange in den Begriffen von MIT 6.006?
    • insert last und delete last
    • insert last und delete first
    • insert first und delete first
    • get at und set at
Das Wichtigste
  • Eine Warteschlange ist first in, first out: hinten einreihen, vorn entnehmen.
  • shift verschiebt jeden übrigen Wert, also kostet das Entnehmen aus n Werten n Schritte.
  • Ein head-Index oder ein Ringpuffer macht das Entnehmen zu 1 Schritt.
  • In einem Ring der Größe c ist die nächste freie Zelle (head + size) mod c.
Quellen zu diesem Kurs (11)
  • MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
  • lecture notes 2 Data Structures (interface vs data structure, Sequence and Set interfaces, stack = insert_last/delete_last, queue = insert_last/delete_first, array, linked list, dynamic array, amortized Θ(1) append)
  • 4 Hashing (chaining, pigeonhole collisions, chain length n/m)
  • 6 Binary Trees Part 1 (height, traversal order, O(h) operations) and 7 Binary Trees Part 2: AVL (Adelson-Velsky and Landis, 1962) at ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes
  • MDN Web Docs, Array.prototype.shift (shifts all values left by 1)
  • Array.prototype.unshift, Map (insertion order, Map vs Object, spec requires sublinear average access) and Set (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
  • ECMAScript 2025 Language Specification (tc39.es/ecma262)
  • 24.1 Map Objects and 24.2 Set Objects ("must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements")
  • Array.prototype.shift steps (Repeat, while k < len: move element k to k - 1)
  • D. E. Knuth, The Art of Computer Programming vol. 3 (2nd ed. 1998) section 6.4 History (H. P. Luhn, IBM internal memorandum January 1953, hashing with chaining; digit pairs added mod 10, 31415926 -> 4548) via gwern.net copy, and IEEE Spectrum, "Hans Peter Luhn and the Birth of the Hashing Algorithm" (2018)
  • "A brief history of the stack", SIGCIS (sigcis.org/files/A brief history.pdf: Bauer and Samelson applied for the patent in 1957, US 3,047,228 granted July 31, 1962; IPL list processing by Newell, Simon and Shaw at RAND 1956) and Wikipedia, Information Processing Language (Newell, Shaw, Simon, RAND and Carnegie Institute of Technology, about 1956).

Abgerufen: 2026-10-18