image: data-structures-avl.webp kind: projekt topic: sandboxes reference: [gitlab] template: https://github.com/specht/data-structures-sandbox.git class_repo: git@git.nhcham.org:specht/data-structure-sandbox-structures-2026.git template_name: der Data Structures Sandbox

Datenstrukturen von innen sehen

In der Data Structures Sandbox programmierst du Listen, Stacks, Queues, Bäume, Heaps und Hash-Tabellen selbst, in Dart, Python, JavaScript oder Java, und siehst bei jedem Methodenaufruf, was in deinem Speicher passiert: welche Zelle beschrieben wird, welche Referenz umgebogen wird, welcher Knoten rotiert.

Vier Sprachen, eine App: Du programmierst deine Datenstrukturen in Dart, Python, JavaScript oder Java, in der Sprache, die du lernst oder magst. Darstellung und Tests sind für alle vier dieselben. In einer Klasse kann also jede und jeder eine andere Sprache wählen, und ihr vergleicht trotzdem dieselben Strukturen.

1. Worum es geht

Die meisten Programmiersprachen bringen fertige Listen, Mengen und Wörterbücher mit. Gerade deshalb bleibt oft unklar, was darin eigentlich passiert. In der Sandbox gibt es diese Abkürzung nicht: Eine Array-Liste besteht aus acht festen Speicherzellen, eine verkettete Liste aus Knoten mit next-Referenz, und die Größe ist ein Feld size, das du selbst pflegst. Die Darstellung zeigt genau diesen Speicher; sie räumt nichts auf und rechnet nichts nach.

Jede Struktur gibt es als unfertigen Starter und als vollständiges Referenzbeispiel. Du schreibst nur die Logik, keinen Code zum Zeichnen. Ins Eingabefeld oben tippst du Methodenaufrufe wie insert(30); insert(20), drückst Enter und spulst den Ablauf dann Schritt für Schritt vor und zurück.

Du arbeitest mit zwei Git-Repositories. Im Workspace ist ~ dein Ordner /workspace.

Ordner Inhalt Wer ändert es?
~/data-structures-sandbox/ die App nur deine Lehrkraft
~/data-structures-sandbox/structures/ das Klassen-Repository mit euren Implementierungen ihr, jede und jeder im eigenen Ordner

Die Karten auf dieser Seite schauen in deinem Workspace nach und sagen dir, was sie finden. Sie ändern nichts.

2. Einrichten

Einmalig: Zugang zu GitLab

Mit einem SSH-Schlüssel meldet sich dein Workspace beim GitLab-Server an, ohne dass du jedes Mal ein Passwort eingibst. Melde dich zuerst auf git.nhcham.org an. Prüfe dann im Terminal, ob du schon einen Schlüssel hast:

ls ~/.ssh/id_ed25519.pub

Erscheint No such file or directory, erzeugst du einen neuen. Bestätige den vorgeschlagenen Speicherort mit Enter; die Passphrase darfst du im Workspace leer lassen und noch zweimal Enter drücken:

ssh-keygen -t ed25519 -C "Vorname Nachname"

Zeige nun den öffentlichen Schlüssel an und kopiere die ganze Zeile, die mit ssh-ed25519 beginnt:

cat ~/.ssh/id_ed25519.pub

In GitLab gehst du oben rechts auf dein Profilbild und dann auf Edit profile → Access → SSH keys → Add new key. Füge die Zeile bei Key ein, gib als Titel zum Beispiel Workspace an und speichere.

Die Datei ~/.ssh/id_ed25519 ohne .pub ist dein privater Schlüssel. Den kopierst du nie und lädst ihn nirgendwo hoch.

Teste die Verbindung. Beim ersten Mal fragt SSH nach, ob du dem Server vertraust; antworte mit yes. Danach begrüßt dich GitLab mit deinem Benutzernamen:

ssh -T git@git.nhcham.org

Meldet SSH Permission denied (publickey), fehlt der Schlüssel in GitLab, oder du hast eine andere Zeile kopiert als die aus id_ed25519.pub.

Aufgabe 1Dein Schlüssel

Dein öffentlicher SSH-Schlüssel liegt in ~/.ssh/id_ed25519.pub.

Tipp

~ ist im Workspace /workspace. ls ~/.ssh zeigt, was dort liegt.

Jeder Commit trägt einen Namen und eine E-Mail-Adresse. Trage deinen echten Namen und die E-Mail-Adresse deines GitLab-Kontos ein:

git config --global user.name "Vorname Nachname"
git config --global user.email "deine.mail@example.org"

Das ist in jedem Workspace nur einmal nötig. Ohne diese Angaben weigert sich Git zu committen.

Aufgabe 2Git kennt dich

Git kennt deinen Namen und die E-Mail-Adresse deines GitLab-Kontos.

Einmalig: Klonen

Klone die App in dein Home-Verzeichnis:

cd ~
git clone https://github.com/specht/data-structures-sandbox.git

Wechsle in ihren Ordner und klone dort das Klassen-Repository:

cd data-structures-sandbox
git clone git@git.nhcham.org:specht/data-structure-sandbox-structures-2026.git structures

Das Klassen-Repository muss in der App liegen und genau structures heißen. Gibt es structures/ schon, klone es nicht noch einmal und lösche nichts, sondern frag nach.

Aufgabe 3Die Sandbox ist da

Die App liegt in ~/data-structures-sandbox, das Klassen-Repository darin in structures.

Aufgabe 4Ein eigenes Repository

structures ist ein eigenes Git-Repository und weiß, wohin es pushen kann.

3. Arbeiten

Die App starten

Starte die App in einem Terminal und lass es offen. Für Git öffnest du ein zweites Terminal.

cd ~/data-structures-sandbox
./run

Deine erste Datenstruktur legst du im Ordner der App an. Ersetze DEIN_NAME durch deinen Ordnernamen:

cd ~/data-structures-sandbox
./new-structure DEIN_NAME stack array --lang python

Das legt structures/DEIN_NAME/my_array_stack.py an. Vorhandene Dateien werden nie überschrieben. Statt python geht auch dart, javascript oder java.

Ein Datentyp, mehrere Speicherformen

Ein Stack arbeitet nach dem LIFO-, eine Queue nach dem FIFO-Prinzip. Dasselbe Verhalten lässt sich aber mit einem festen Array, einem Ringpuffer oder verketteten Knoten erreichen. Besonders ergiebig sind die vier Listen: unsortiert oder sortiert, jeweils als Array oder als verkettete Knoten. Alle vier haben dieselbe Schnittstelle, und du kannst dieselbe Folge von Aufrufen auf alle vier loslassen. Hier eine Folge von Einfügungen auf einer einfach verketteten Liste, in Java implementiert:

Einfach verkettete Liste in Java nach vier Einfügungen: Knoten und next-Referenzen neben dem Quelltext.

Dieselben Aufrufe, zwei Welten. Lass insert(0,7); insert(1,3); insert(1,5); insert(3,9) zuerst auf der Array-Liste und dann auf der verketteten Liste laufen. Welche Operation verschiebt Werte, welche biegt nur Referenzen um? Warum geht get(i) beim Array in konstanter Zeit, während die verkettete Liste dafür bis zu n Knoten ablaufen muss? Und was kostet umgekehrt das Einfügen ganz vorne?

Die Tests sind streng, und das ist gewollt: Eine Liste gilt erst dann als richtig, wenn sie sich nach außen richtig verhält und ihr Inneres stimmt, etwa wenn size wirklich der Zahl der gespeicherten Werte entspricht oder die Knotenkette keinen Kreis enthält. Ungültige Indizes, volle Arrays und doppelte Werte gehören fest zur Prüfung.

Bäume, Rekursion und AVL-Rotationen

Bei binären Suchbäumen wird die Suchregel sichtbar: links das Kleinere, rechts das Größere. Rekursive Aufrufe verfolgst du Schritt für Schritt und siehst, an welchem Knoten gerade gearbeitet wird. AVL-Bäume speichern zusätzlich die Höhe ihrer Teilbäume und stellen das Gleichgewicht nach dem Einfügen durch Rotationen wieder her. Hier ein AVL-Baum, in Python implementiert, nach sechs Einfügungen:

AVL-Baum in Python nach sechs Einfügungen und zwei Rotationen.

Erst skizzieren, dann rotieren. Skizziere nach insert(30); insert(20); insert(10) zuerst den unbalancierten Baum und begründe, welche Rotation ihn rettet. Dann lass die Sandbox nachrechnen. Zum Vergleich: Was passiert mit einem gewöhnlichen Suchbaum, wenn du 1, 2, 3, … 10 der Reihe nach einfügst?

Hash-Tabellen: Du entscheidest

Die Hash-Tabelle löst Kollisionen durch Verkettung (separate chaining). Wie viele Buckets es gibt und welche Hashfunktion verwendet wird, legst du in deiner eigenen Klasse fest; die Tests akzeptieren jede gültige Wahl. So werden Kollisionen und Lastfaktor zu etwas, das du gezielt herbeiführen und vermeiden kannst.

Hash-Tabelle mit acht Buckets, in denen sich kollidierende Schlüssel zu Ketten verbinden.

Kollisionen provozieren. Finde fünf Schlüssel, die alle im selben Bucket landen. Was passiert mit der Suche? Ändere dann die Zahl der Buckets von 8 auf 7 oder 11 und wiederhole die Folge. Welche Bucketzahlen sind eine schlechte Idee, wenn die Schlüssel zum Beispiel alle gerade sind?
Zum Weiterdenken: Wohin gehört der Schlüssel −7 bei acht Buckets? Die Antwort hängt von der Sprache ab: In Dart und Python ergibt -7 % 8 den Wert 1, in Java und JavaScript −7, also einen ungültigen Index. Die Referenzbeispiele der Sandbox lösen das in jeder Sprache anders (Math.floorMod in Java, eine kleine Formel in JavaScript). Was ist eigentlich ein »Rest«?

Werkzeuge der App

  • Repeat spielt deine Aufruffolge nach jedem Speichern automatisch erneut ab: Du siehst sofort, was deine Änderung bewirkt.
  • Run tests prüft Methoden und inneren Aufbau gegen unabhängige Vergleichsmodelle und nennt bei einem Fehler den konkreten Fall.
  • Ausgaben mit print erscheinen in der Konsole genau an dem Schritt, an dem sie entstanden sind; Laufzeitfehler springen auf Wunsch zur passenden Zeile.

Neben den gezeigten Strukturen gibt es Stacks und Queues jeweils als Array und als Knotenkette sowie einen Min-Heap im Array. Mehr zur App steht in ihrer Anleitung, was jede Struktur genau können muss in den Verträgen.

4. Veröffentlichen

Deine Lehrkraft sieht deine Arbeit erst, wenn sie committet und gepusht ist. Das machst du im Ordner structures, nicht im Ordner der App:

cd ~/data-structures-sandbox/structures
git pull
git add DEIN_NAME/
git commit -m "Array-Stack von DEIN_NAME"
git push
Aufgabe 5Was gehört in deinen Commit?

Im Klassen-Repository arbeiten alle. Mit welchem Befehl nimmst du nur deine eigenen Dateien in den nächsten Commit auf?

Was gehört in deinen Commit?
Aufgabe 6Committet und gepusht

Deine Arbeit ist committet und gepusht. Erst dann sieht deine Lehrkraft sie in »Class progress«. Prüfe das am Ende jeder Stunde.

In einem Klassen-Repository veröffentlichen viele. Hat jemand kurz vor dir gepusht, lehnt Git deinen Push mit rejected ab, weil dir dessen Commits fehlen. Hol sie zuerst und push dann noch einmal:

git pull
git push

Öffnet git pull einen Editor für eine Commit-Nachricht, speichere sie unverändert und schließe den Editor. Meldet Git einen Konflikt, hat jemand dieselbe Datei geändert wie du. Dann gilt: nichts löschen, nichts überschreiben, nach Hilfe fragen. Solange du nur Dateien in deinem eigenen Ordner änderst, passiert das nicht.

5. Beim nächsten Mal

cd ~/data-structures-sandbox && git pull
cd structures && git pull
cd .. && ./run

Und am Ende der Stunde: Aufgabe 5 noch einmal prüfen.