Verkettete Listen
Einen Wert vorn in eine verkettete Liste einzufügen, ändert zwei Zeiger, ob die Liste 4 Werte enthält oder 4 Millionen.
Werte, die auf den nächsten zeigen
Ein Array hält seine Werte Seite an Seite, deshalb ist eine Änderung am Anfang teuer. Eine verkettete Liste verzichtet auf diese Regel. Jeder Wert wohnt in einem eigenen kleinen Datensatz, einem Knoten, und die Knoten können irgendwo im Speicher liegen. Die Unterlagen von MIT 6.006 beschreiben einen Knoten mit zwei Feldern: dem Element und next, einem Zeiger auf den folgenden Knoten. Die Liste selbst merkt sich nur den ersten Knoten, den head (Kopf). next des letzten Knotens ist null, das markiert das Ende.
Um die Liste zu lesen, beginnst du bei head und folgst den next-Zeigern einem nach dem anderen, wie bei einer Kette von Zetteln, auf denen jeweils steht, wo der nächste versteckt ist. Das hat seinen Preis. Für die Adresse des vierten Knotens gibt es keine Formel, also heißt der Wert an Position i, i + 1 Knoten zu besuchen. MIT gibt get at(i) für eine verkettete Liste mit O(n) an, wo das Array einen Schritt brauchte.
// ein Knoten pro Wert: { value, next }
let head = null;
for (const v of [4, 30, 7, 12]) head = { value: v, next: head };
// die Liste durchlaufen
for (let n = head; n !== null; n = n.next) console.log(n.value); // 12, 7, 30, 4Die Liste durch Umhängen ändern
Der Gewinn kommt, wenn du die Liste änderst. Um einen neuen Wert vorn einzufügen, leg einen Knoten an, dessen next der aktuelle head ist, und lass dann head auf den neuen Knoten zeigen. Zwei Zeigeränderungen, und sonst bewegt sich nichts. Den vordersten Knoten zu löschen, ist eine Änderung: head auf head.next zeigen lassen. Vergleich das mit dem Array, wo dieselben Operationen jeden Wert verschoben haben.
In der Mitte besteht die Arbeit darin, die Stelle zu finden. Um an Position i einzufügen, läufst du zum Knoten direkt davor (i Besuche) und machst dann dieselben zwei Zeigeränderungen: new.next = prev.next, dann prev.next = new. Die Reihenfolge ist wichtig. Setzt du zuerst prev.next, geht der Rest der Liste verloren, weil nichts mehr auf ihn zeigt. Im Labor ist ein Schritt ein besuchter Knoten oder ein geänderter Zeiger, also kostet Einfügen an Position 2 einer Liste mit 4 Knoten 2 Besuche plus 2 Änderungen, 4 Schritte.
Zum Drehen ziehen. Zum Zoomen scrollen oder mit zwei Fingern ziehen.
| Operation | Array (n Werte) | Verkettete Liste (n Knoten) |
|---|---|---|
| Den Wert an Position i holen | 1 | i + 1 Besuche |
| Am Anfang einfügen | n Verschiebungen + 1 Schreibvorgang | 2 Zeigeränderungen |
| Den Anfang löschen | 1 Lesevorgang + (n − 1) Verschiebungen | 1 Zeigeränderung |
| An Position i einfügen | (n − i) Verschiebungen + 1 Schreibvorgang | i Besuche + 2 Änderungen |
| Einen Wert finden | bis zu n Lesevorgänge | bis zu n Besuche |
Wann man sie nimmt
Eine verkettete Liste passt gut, wenn die meisten Änderungen an einer Stelle passieren, auf die du schon einen Zeiger hast, etwa vorn, und du selten Position i brauchst. Warteschlangen und Stapel lassen sich aus verketteten Listen bauen, ebenso die Ketten in einer Hashtabelle aus der nächsten Einheit. Es gibt Varianten. Eine doppelt verkettete Liste gibt jedem Knoten zusätzlich einen prev-Zeiger, sodass man rückwärts laufen und einen Knoten, den man schon hat, in einem Schritt löschen kann. Wer neben head auch einen tail-Zeiger führt, kann billig am Ende anfügen.
Im JavaScript-Alltag schreibst du selten eine verkettete Liste, weil Arrays gut optimiert sind und die Caches moderner Prozessoren Werte bevorzugen, die nebeneinander gespeichert sind. Die Idee zählt trotzdem: Bäume, Graphen und viele Bibliotheksstrukturen sind genau so aus Knoten und Zeigern gebaut.
- Welche zwei Felder hat ein Knoten einer einfach verketteten Liste?
- item und next
- index und value
- left und right
- head und tail
- Liste 12 → 7 → 30 → 4. Wie viele Schritte kostet das Einfügen eines neuen Werts vorn (Zeigeränderungen)?
- Dieselbe Liste: Wie viele Schritte kostet Einfügen an Position 2 (Besuche plus Zeigeränderungen)?
- Dieselbe Liste: Wie viele Knoten besucht eine Suche nach 30?
- Dieselbe Liste: Wie viele Knoten besucht eine Suche nach 99, bevor sie null erreicht?
- Dieselbe Liste: Wie viele Schritte kostet das Löschen des Knotens an Position 3 (die 4)?
- Ein Array enthält 1000 Werte und hat noch Platz. Wie viele Schritte kostet das Einfügen am Anfang?
- Welche Aufgabe passt besser zu einer verketteten Liste als zu einem Array?
- Den Wert an Position 500 oft lesen
- Oft vorn einfügen und entfernen
- Binäre Suche
- Nach Index sortieren
- Welche Reihenfolge der Schritte erhält beim Einfügen hinter Knoten p den Rest der Liste?
- p.next = new, dann new.next = p.next
- new.next = p.next, dann p.next = new
- Beide Reihenfolgen funktionieren
- Zuerst p löschen
- Welche Sprache, um 1956 bei RAND geschrieben, führte Listenverarbeitung mit verketteten Zellen ein?
- Fortran
- IPL
- C
- JavaScript
- Eine verkettete Liste speichert jeden Wert in einem Knoten mit next-Zeiger; die Liste hält head.
- Einfügen oder Löschen vorn ändert 1 oder 2 Zeiger; nichts bewegt sich.
- Position i zu erreichen, kostet i + 1 Besuche, also ist get at(i) O(n).
- new.next setzen, bevor der vorherige Knoten umgehängt wird.
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