Aufgabenstellung
Loading
Loading
Listen, Stacks, Queues, Bäume, Hashtabellen und Graphen sind die Grundbausteine effizienter Programme. Datenstrukturen entscheiden über Laufzeit und Speicher; ihre Wahl ist Teil jeder Algorithmus-Aufgabe.
6Abschnitteca. 21Min Lesezeit4KompetenzenNiveauBasis 1 · Standard 2 · Vertiefung 3Stand 06/2026
Lesetiefe: Vertiefung
Schriftgröße: Standard
Stack (LIFO) und Queue (FIFO)
Einfach verkettete Liste
Prüfe mit einem Stack, ob die Zeichenkette "{[()]}" korrekt geklammert ist.
Leerer Stack S. Lese Zeichen von links nach rechts.
S = [ "{" ].
S = [ "{", "[" ].
S = [ "{", "[", "(" ].
Top "(" passt zu ")"; S = [ "{", "[" ].
Top "[" passt zu "]"; S = [ "{" ].
Top "{" passt zu "}"; S = [ ].
Stack leer -> Ausdruck korrekt geklammert.
Ergebnis: Algorithmus liefert true. Laufzeit O(n), Speicher O(n) im Worst Case.
Stack und Queue sind die zwei gegensätzlichsten linearen Datenstrukturen: gleicher Container, andere Bedienungsrichtung.
Stack (LIFO) und Queue (FIFO)
In jedem Compiler steckt ein Stack für die Funktionsaufrufe; in jedem Drucker eine Queue für die Druckaufträge.
Linked List ist immer dann sinnvoll, wenn du wenig wahlfreien Zugriff, aber häufig Einfügen vorne brauchst.
Einfach verkettete Liste
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Implementiere in Python eine Klasse `Queue` mit den Methoden enqueue, dequeue, peek und size unter Verwendung einer verketteten Liste. Welche Laufzeit haben die Operationen?
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: Pat Morin: Open Data Structures (Carleton University)
Binärer Suchbaum (BST)
Höhe eines BST mit n Knoten
Konstruiere den BST, der entsteht, wenn die Werte in der gegebenen Reihenfolge eingefügt werden.
8 wird Wurzel.
3 < 8 -> links von 8.
10 > 8 -> rechts von 8.
1 < 8, 1 < 3 -> links von 3.
6 < 8, 6 > 3 -> rechts von 3.
14 > 8, 14 > 10 -> rechts von 10.
4 < 8, 4 > 3, 4 < 6 -> links von 6.
7 < 8, 7 > 3, 7 > 6 -> rechts von 6.
Ergebnis: Inorder-Traversierung liefert 1, 3, 4, 6, 7, 8, 10, 14 - das ist die sortierte Folge.
Im BST gilt links kleiner, rechts größer - daher liefert Inorder direkt die sortierte Liste.
Binärer Suchbaum (BST)
Wenn du bewusst sortierte Daten einfügst, entartet der BST zu einer Liste mit Operationen.
AVL und Red-Black-Bäume balancieren automatisch, indem sie Knoten rotieren.
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Konstruiere den BST für die Einfügefolge 50, 30, 70, 20, 40, 60, 80, 10. Lies die Inorder-Traversierung ab.
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: Open Data Structures - Chapter 6/7 (Pat Morin)
Hash-Tabelle mit Separate Chaining
Erwartete Suchschritte vs. Lastfaktor α
Kollisionen pro Bucket (m=10 Slots, n=20 Schlüssel)
Lastfaktor und erwartete Suchzeit in einer Hashtabelle
Füge Schlüssel 19, 26, 14, 7, 33, 12 in eine Hashtabelle der Größe mit ein (Chaining).
19 mod 7 = 5; 26 mod 7 = 5; 14 mod 7 = 0; 7 mod 7 = 0; 33 mod 7 = 5; 12 mod 7 = 5.
Bucket 0: [14, 7]; Bucket 5: [19, 26, 33, 12].
- hoch, Performance sinkt.
Hash 5, Liste durchsuchen: 19, 26, 33 (gefunden in 3 Schritten).
Ergebnis: Bucket 5 ist stark belegt (4 von 6 Schlüsseln). Bessere Hashfunktion oder größeres würde gleichmäßiger streuen.
Eine Hashtabelle wandelt Schlüssel in Array-Indizes um - das ist der Trick für konstante Suchzeit.
Hash-Tabelle mit Separate Chaining
Kollisionen sind unvermeidbar (Schubfachprinzip); entscheidend ist eine schnelle Auflösung.
Wenn der Lastfaktor steigt, vergrößere die Tabelle und hash neu - sonst sinkt die Performance.
Erwartete Suchschritte vs. Lastfaktor α
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Füge die Schlüssel 19, 26, 14, 7, 33, 12 in eine Hashtabelle der Größe mit und Linear Probing ein. Notiere den finalen Belegungszustand.
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: MDN - Map (JavaScript) (Mozilla) · CPython dict implementation notes (PSF)
Gewichteter gerichteter Graph (Dijkstra-Beispiel)
Maximale Kantenzahl im einfachen ungerichteten Graphen
Führe BFS auf dem Graphen A-B, A-C, B-D, C-D, D-E ab Knoten A durch.
Queue Q = [A], visited = {A}.
Dequeue A. Nachbarn B, C nicht in visited -> enqueue. Q = [B, C], visited = {A, B, C}.
Dequeue B. Nachbarn A (besucht), D -> enqueue. Q = [C, D], visited = {A, B, C, D}.
Dequeue C. Nachbarn A, D bereits besucht. Q = [D].
Dequeue D. Nachbar E -> enqueue. Q = [E], visited = {A, B, C, D, E}.
Dequeue E. Keine neuen Nachbarn.
Ergebnis: Besuchsreihenfolge: A, B, C, D, E. Distanzen ab A: A=0, B=1, C=1, D=2, E=3.
Bestimme die kürzesten Wege ab A im gerichteten Graphen mit Kanten A->B (4), A->C (2), B->C (1), B->D (5), C->B (1), C->D (8), C->E (10), D->E (2). Führe die Distanz/Vorgänger-Tabelle Schritt für Schritt.
dist[A]=0, alle anderen . Min-Heap PQ = {(0,A)}. visited = {}.
Relaxiere A->B: dist[B]=4 (Vorg. A); A->C: dist[C]=2 (Vorg. A). PQ = {(2,C),(4,B)}.
C hat die kleinste Distanz. Relaxiere C->B: 2+1=3 < 4, also dist[B]=3 (Vorg. C); C->D: dist[D]=10 (Vorg. C); C->E: dist[E]=12 (Vorg. C). PQ = {(3,B),(10,D),(12,E)}.
Relaxiere B->C (bereits final, überspringen); B->D: 3+5=8 < 10, also dist[D]=8 (Vorg. B). PQ = {(8,D),(12,E)}.
Relaxiere D->E: 8+2=10 < 12, also dist[E]=10 (Vorg. D). PQ = {(10,E)}.
E hat keine ausgehenden Kanten. PQ leer -> fertig.
Ergebnis: Endgültige Distanzen ab A: A=0, C=2, B=3, D=8, E=10. Kürzester Weg A->E = A->C->B->D->E (Länge 10) - günstiger als der direkte A->B (4) oder A->C->E (12), weil B über C auf 3 relaxiert wird.
Ein Graph ist die universelle Datenstruktur für Netzwerke - vom Verkehrsnetz bis zum sozialen Graph.
BFS und DFS sind dieselbe Idee mit unterschiedlicher Wartespeicher-Struktur: Queue oder Stack.
Dijkstra nutzt einen Min-Heap, um stets den naechst-naehesten Knoten zu expandieren.
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Gegeben Graph mit Knoten {A,B,C,D,E} und Kanten A-B, A-C, B-D, C-D, D-E. Führe BFS ab Knoten A durch und liste die Besuchsreihenfolge auf.
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: CLRS - Graph Algorithms (Kap. 22-24) (MIT Press)
AVL-Rechtsrotation nach LL-Imbalance
Balancefaktor eines AVL-Knotens
Obere Höhenschranke des AVL-Baums
Füge 3, 2, 1 in einen leeren AVL-Baum ein und stelle die Balance wieder her.
Wurzel = 3, Balancefaktor 0. Baum ist balanciert.
2 < 3, wird linkes Kind. Balancefaktor von 3 ist (linke Höhe 1, rechte 0). Noch zulässig.
1 < 3, 1 < 2, wird linkes Kind von 2. Balancefaktor von 3 ist nun - Verletzung. Erste zwei Kanten gehen links-links: LL-Fall.
Knoten 2 wird neue Wurzel; 1 bleibt linkes Kind, 3 wird rechtes Kind von 2.
Inorder vorher 1,2,3 und nachher 1,2,3 - Ordnung erhalten. Alle Balancefaktoren sind 0.
Ergebnis: Nach der Rechtsrotation ist 2 die Wurzel mit Kindern 1 und 3; der Baum ist mit Höhe 1 wieder balanciert.
Füge 5, 2, 4 in einen leeren AVL-Baum ein und balanciere.
5 als Wurzel; 2 als linkes Kind (bf von 5 = +1).
4 > 2, also rechtes Kind von 2; 4 < 5. Balancefaktor von 5 wird , erste Kanten links-rechts: LR-Fall.
Teilbaum 2-4 wird zu 4-2: 4 wird linkes Kind von 5, 2 wird linkes Kind von 4. Jetzt liegt der LL-Fall vor.
4 wird Wurzel; 2 linkes Kind, 5 rechtes Kind.
Ergebnis: Endbaum: Wurzel 4 mit Kindern 2 und 5; Inorder 2,4,5 bleibt korrekt, Baum balanciert.
Ohne Balancierung entartet ein BST bei sortierten Daten zur Liste - genau das verhindern AVL-Bäume.
Der Balancefaktor ist die Höhendifferenz der Teilbäume; sobald er +-2 erreicht, wird rotiert.
AVL-Rechtsrotation nach LL-Imbalance
Merksatz: gerade Kette (LL/RR) eine Rotation, Knick (LR/RL) zwei Rotationen.
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Füge nacheinander 10, 20, 30 in einen anfangs leeren AVL-Baum ein. Bestimme nach jedem Schritt den Balancefaktor der Wurzel, identifiziere den Imbalance-Fall und führe die nötige Rotation durch.
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: Open Data Structures - Scapegoat & balanced trees (Pat Morin)
Min-Heap als Baum und als Array
Array-Einbettung eines Binaer-Heaps
Füge 7, 3, 9, 1, 5 in einen leeren Min-Heap ein und entnimm danach das Minimum.
[7]; dann 3 ans Ende -> [7,3], 3<7 also sift-up -> [3,7].
[3,7,9]; 9>3, kein sift-up nötig.
[3,7,9,1]; 1 an Index 3, Elter Index 1 = 7, 1<7 -> tauschen -> [3,1,9,7]; jetzt 1<3 -> tauschen -> [1,3,9,7].
[1,3,9,7,5]; 5 an Index 4, Elter Index 1 = 3, 5>3 -> kein Tausch. Heap fertig.
Wurzel 1 entnehmen; letztes Element 5 an die Wurzel -> [5,3,9,7]; sift-down: kleineres Kind ist 3 (Index 1), 5>3 -> tauschen -> [3,5,9,7]. Heap-Eigenschaft erfüllt.
Ergebnis: Min-Heap vor Entnahme: [1,3,9,7,5]; extract-min liefert 1, danach [3,5,9,7].
Ein Heap speichert ein Minimum (oder Maximum) so, dass es immer in konstanter Zeit verfuegbar ist.
Min-Heap als Baum und als Array
Weil der Baum vollständig ist, passt er luckenlos in ein Array - Zeiger sind unnötig.
insert wandert mit sift-up nach oben, extract-min repariert mit sift-down nach unten.
SRDP-Aufgaben
Aufgabenstellung
Typische Fehler
Aktive Wiederholung
Füge die Werte 7, 3, 9, 1, 5 nacheinander in einen anfangs leeren Min-Heap ein und gib nach jedem Einfügen die Array-Darstellung an. Führe anschliessend ein extract-min durch.
Aktiv abrufen
Erinnere dich an die Kernpunkte — dann aufdecken.
Quellen: OpenDSA - Heaps and Priority Queues (Virginia Tech)
Belege & Quellen
Carleton University
Pat Morin
Mozilla
MIT Press
Virginia Tech