Klasse 11 · Informatik · Doppelstunde 2

Knoten, Zeiger,
Verkettung

Wenn Arrays nicht reichen: Verkettete Listen als flexible Datenstruktur — Konzept, Implementierung und Anwendung in Python.

Verkettete Listen Stack & Queue Python-Implementierung
Modul 01

Das Konzept

Eine verkettete Liste besteht aus Knoten — jeder Knoten speichert einen Datenwert und einen Zeiger auf den nächsten Knoten. Es gibt keinen zusammenhängenden Speicherblock.

🔗 Der Knoten (Node)

Jeder Knoten ist ein Objekt mit zwei Feldern: dem Datenwert und dem Zeiger auf den Nachfolger.

↓ Details anzeigen
Aufbau eines Knotens:

[ data | next → ]
data: der gespeicherte Wert (beliebiger Typ)
next: Referenz auf den nächsten Knoten (oder None am Ende)

In Python implementiert man das mit einer einfachen Klasse: class Node mit den Attributen self.data und self.next.

👑 Kopf & Schwanz

Die Liste kennt nur den ersten Knoten (head). Der letzte Knoten hat next = None.

↓ Details anzeigen
head ist der Einstiegspunkt der ganzen Liste. Ohne head ist die Liste verloren — man hat keinen Zugriff mehr auf die Knoten.

tail (optional) kann zusätzlich gespeichert werden, um das Anhängen am Ende von O(n) auf O(1) zu beschleunigen.

Der None-Pointer am letzten Knoten ist das Terminierungssignal — er sagt: „Hier ist die Liste zu Ende."

🔀 Einfach vs. Doppelt

Einfach verkettet: jeder Knoten zeigt nur vorwärts. Doppelt verkettet: auch rückwärts.

↓ Details anzeigen
Einfach verkettet (SLL): [data|next→]
→ Traversierung nur vorwärts, weniger Speicher

Doppelt verkettet (DLL): [←prev|data|next→]
→ Traversierung in beide Richtungen, Löschen effizienter

Pythons eingebaute collections.deque ist intern eine doppelt verkettete Liste!

⏱️ Zeitkomplexität

Wo ist die verkettete Liste schneller als ein Array — und wo langsamer?

↓ Details anzeigen
O(1) — schnell:
• Einfügen/Löschen am Anfang (wenn head bekannt)
• Einfügen am Ende (wenn tail bekannt)

O(n) — langsam:
• Zugriff per Index (muss von head durchlaufen)
• Suchen eines Wertes
• Einfügen/Löschen in der Mitte

Arrays sind bei Indexzugriff O(1), bei Einfügen am Anfang O(n).

Array (Python-Liste)

  • Zusammenhängender Speicherblock
  • Indexzugriff in O(1)
  • Einfügen am Anfang: O(n) — alle verschieben
  • Feste oder übervorsichtig reservierte Größe
  • Cache-freundlich (locality of reference)
  • Gut für: Suchen, zufälliger Zugriff

Verkettete Liste

  • Verteilt im Heap — keine Nachbarschaft nötig
  • Indexzugriff: O(n) — immer vom head
  • Einfügen am Anfang: O(1) — nur Zeiger ändern
  • Wächst dynamisch ohne Umkopieren
  • Mehr Speicher pro Element (Zeiger!)
  • Gut für: häufiges Einfügen/Löschen
Modul 02

Interaktiver Visualizer

Baue eine verkettete Liste Schritt für Schritt auf. Beobachte, wie sich die Zeiger-Verbindungen bei jeder Operation verändern.

— Liste ist leer. Füge Elemente hinzu —
Nutze die Buttons, um Elemente einzufügen oder zu löschen. Beobachte, wie sich die Zeiger verändern.
Länge: 0  |  Head: None  |  Tail: None
Modul 03

Python Programmieren

Jetzt selbst ran: Vier Aufgaben mit Listen, Stack und Queue — ohne Klassen, nur mit dem, was du schon kennst.

🔍 Aufgabe 1 — Liste erkunden

Eine fertige verkettete Liste liegt als verschachteltes Dictionary vor. Schreibe Code, der alle Werte der Reihe nach ausgibt — genau wie der Visualizer oben.

aufgabe1_erkunden.py
⚠ input() nicht verfügbar
Ausgabe
— noch keine Ausgabe —

📚 Aufgabe 2 — Stack: Klammerprüfung

Ein Stack ist perfekt für die Prüfung von Klammern. Ergänze die fehlenden Zeilen in der Funktion.

aufgabe2_klammern.py
⚠ input() nicht verfügbar
Ausgabe
— noch keine Ausgabe —

🖨️ Aufgabe 3 — Queue: Druckerwarteschlange

Simuliere eine Druckerwarteschlange. Dokumente werden hinten eingefügt und vorne gedruckt.

aufgabe3_drucker.py
⚠ input() nicht verfügbar
Ausgabe
— noch keine Ausgabe —

🎯 Aufgabe 4 — Eigenes Szenario

Wähle selbst: Implementiere entweder eine Browser-Verlauf-Simulation (Stack: zurück-Button) oder eine Ticketkasse (Queue: Kunden werden der Reihe nach bedient). Starte mit dem Grundgerüst.

aufgabe4_eigenes.py
⚠ input() nicht verfügbar
Ausgabe
— noch keine Ausgabe —
Modul 04

Stack & Queue

Verkettete Listen sind die natürliche Grundlage für zwei wichtige abstrakte Datenstrukturen: Stack (LIFO) und Queue (FIFO).

📚 Stack (LIFO)

Last In, First Out — wie ein Bücherstapel. Das zuletzt gelegte Buch wird zuerst genommen.

↓ Details anzeigen
Operationen:
push(x) — Element oben drauflegen: O(1)
pop() — Oberstes Element nehmen: O(1)
peek() — Oberstes nur ansehen: O(1)

Anwendungen: Funktionsaufruf-Stack (Call Stack), Rückgängig-Funktion (Undo), Klammerprüfung in Compilern, Tiefensuche (DFS).

🚉 Queue (FIFO)

First In, First Out — wie eine Warteschlange. Wer zuerst kommt, wird zuerst bedient.

↓ Details anzeigen
Operationen:
enqueue(x) — Hinten anstellen: O(1)
dequeue() — Vorne rausnehmen: O(1)
peek() — Vorderstes ansehen: O(1)

Anwendungen: Druckerwarteschlange, Prozess-Scheduling, Breitensuche (BFS), Netzwerkpakete.

🐍 Python-Implementierung

Pythons list kann beides — aber collections.deque ist effizienter für Queue.

↓ Details anzeigen
Stack mit list:
s = []; s.append(x); s.pop() Queue mit deque:
from collections import deque q = deque(); q.append(x); q.popleft() list.pop(0) für Queue ist O(n) — deque.popleft() ist O(1)!
Stack
LIFO — Last In, First Out
— Stack ist leer —
Drücke Push oder Pop
Queue
FIFO — First In, First Out
— Queue ist leer —
Drücke Enqueue oder Dequeue

🔬 Ausprobieren: Stack & Queue in Python

stack_queue.py
⚠ input() nicht verfügbar
Ausgabe
— noch keine Ausgabe —

Wissen testen

8 Fragen zu verketteten Listen, Stack und Queue — von Grundwissen bis kritischem Denken.

① Grundwissen
② Verständnis
③ Anwendung
④ Kritisch
0/8
Punkte erreicht

Wann lohnt sich eine verkettete Liste wirklich?

„In der Praxis sind Python-Listen fast immer schneller als selbst implementierte verkettete Listen — dank Cache-Optimierungen. Aber das Konzept dahinter ist die Grundlage für Bäume, Graphen und mehr."
Verkettete Liste wählen wenn… Sehr häufig am Anfang/Ende eingefügt oder gelöscht wird. Die Gesamtgröße nicht vorhersehbar ist. Kein wahlfreier Zugriff per Index benötigt wird.
Array / Python-Liste wählen wenn… Oft per Index zugegriffen wird. Iteration über alle Elemente wichtig ist. Performance durch CPU-Cache entscheidend ist.
Diskussion Kann man einen Stack oder eine Queue auch mit einem Array effizient implementieren? Was sind die Trade-offs? Wo in Python's Standardbibliothek stecken verkettete Listen?