diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d628793 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Compiled C executables +*.o +*.out +*.exe +quicksort_test +quicksort_mit_zeigern_test +quicksort_* + +# Rust +Rust_Version/target/ +**/*.rs.bk +Cargo.lock + +# OS files +.DS_Store +Thumbs.db + +# Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Build artifacts +*.map +*.min.js +dist/ +build/ + +# Node modules (if ever added) +node_modules/ + +# Logs +*.log diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md new file mode 100644 index 0000000..cd41a7c --- /dev/null +++ b/BEDIENUNGSANLEITUNG.md @@ -0,0 +1,325 @@ +# Bedienungsanleitung — Sortier-Algorithmen Visualisierung + +## Inhalt + +1. [Was ist das?](#1-was-ist-das) +2. [Oberfläche](#2-oberfläche) +3. [Schnellstart](#3-schnellstart) +4. [Auswahlmöglichkeiten](#4-auswahlmöglichkeiten) +5. [Steuerung](#5-steuerung) +6. [Tastaturkürzel](#6-tastaturkürzel) +7. [Farbcode](#7-farbcode) +8. [Statistik-Karten](#8-statistik-karten) +9. [Speicher-Ansicht](#9-speicher-ansicht) +10. [URL-Parameter](#10-url-parameter) +11. [Warum sind Sortieralgorithmen wichtig?](#11-warum-sind-sortieralgorithmen-wichtig) +12. [Algorithmus-Übersicht](#12-algorithmus-übersicht) + +--- + +## 1. Was ist das? + +Dieses Programm visualisiert die Funktionsweise von **20 Sortieralgorithmen** — von Bubble Sort bis Fisher-Yates Shuffle. Es zeigt Schritt für Schritt, wie ein Algorithmus ein Array sortiert, macht die Datenstrukturen und Speichernutzung sichtbar und vermittelt ein intuitives Verständnis dafür, warum der eine Algorithmus schneller ist als der andere. + +**Einschränkung:** Bogo Sort ist auf 8 Elemente begrenzt, da seine O(n·n!)-Komplexität bei größeren Arrays den Browser einfrieren lässt. + +--- + +## 2. Oberfläche + +``` +┌──────────────────────────────────────────────────────────┐ +│ Sortier-Algorithmen [Bedienung] │ +├──────────────┬─────────────────────────────────────────────┤ +│ │ ┌─ Phase-Label ──────────────────────┐ │ +│ Algorithmus │ │ Vergleich: arr[3]=42 mit arr[4]=17 │ │ +│ [Dropdown] │ └────────────────────────────────────┘ │ +│ │ │ +│ Daten │ ┌─────────── Canvas ─────────────────┐ │ +│ [Vorlage] │ │ │ │ +│ │ │ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ │ │ +│ Eigene │ │ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ │ │ +│ Werte │ │ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ │ │ +│ │ │ │ │ +│ Array-Größe │ └────────────────────────────────────┘ │ +│ ─────────── │ │ +│ Geschw. │ [▶][⏸][⏭][🔀][↺][🌙] │ +│ ─────────── │ │ +│ Legend │ Vergleiche: 128 Tausche: 64 Zeit: 1.2s │ +│ │ │ +│ [▶ Play] │ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ │ +└──────────────┴─────────────────────────────────────────────┘ +``` + +- **Links (Sidebar):** Algorithmus wählen, Datensatz, eigene Werte, Geschwindigkeit, Legende +- **Rechts (Hauptbereich):** Canvas mit Animation, Steuerung, Statistik-Karten +- **Unten:** Einklappbare Abschnitte „Über die Algorithmen" und „Bedienung" + +--- + +## 3. Schnellstart + +1. Öffne `sorting_visualization.html` im Browser +2. Wähle einen Algorithmus aus dem Dropdown (z.B. „Quick Sort") +3. Stelle Array-Größe und Geschwindigkeit ein +4. Drücke `Space` zum Starten — oder den Play-Button ▶ + +--- + +## 4. Auswahlmöglichkeiten + +### Algorithmus + +20 Algorithmen in 4 Kategorien: + +| Kategorie | Algorithmen | +|---|---| +| O(n²) — Einfache Verfahren | Bubble Sort, Selection Sort, Insertion Sort, Cocktail Shaker Sort | +| O(n log n) — Effiziente Verfahren | Merge Sort, Heap Sort, Quick Sort, 3-Way Quick Sort, Dual-Pivot Quick Sort, Introsort, Shell Sort, Tree Sort, Timsort | +| O(n·k) — Linear / Nicht-vergleichsbasiert | Counting Sort, Radix Sort, Bucket Sort | +| Spezial | Pancake Sort, Cycle Sort, Bogo Sort, Fisher-Yates Shuffle | + +### Datensatz-Vorlagen (Presets) + +| Vorlage | Beschreibung | +|---|---| +| **Zufall** | Zufällig verteilte Werte — der Standard-Testfall | +| **Sortiert** | Bereits aufsteigend sortiert — manche Algorithmen (z.B. Quick Sort mit erstem Element als Pivot) werden dadurch extrem langsam | +| **Umgekehrt** | Absteigend sortiert — das Gegenstück und ein fairer Test für die meisten Algorithmen | +| **Fast sortiert** | Nur wenige Elemente an der falschen Stelle — adaptiven Algorithmen (Insertion Sort, Timsort) spielen hier ihre Stärke aus | +| **Duplikate** | Viele gleiche Werte — der Härtetest: klassischer Quick Sort degeneriert zu O(n²), 3-Way Quick Sort brilliert hier | + +### Eigene Werte + +Du kannst eigene Zahlen eingeben, getrennt durch Kommas, Leerzeichen oder Zeilenumbrüche. Beispiele: + +``` +5, 3, 8, 1, 9, 2 +``` + +Über den Clipboard-Button kannst du auch direkt aus der Zwischenablage einfügen (Mehrfachpaste wird unterstützt). Die Anzahl der eingegebenen Werte wird oben rechts im Feld angezeigt. + +**Wichtig:** Eigene Werte überschreiben das Preset. Sobald du eigene Werte eingibst, verwendet das Programm diese statt der Vorlage. + +### Array-Größe + +Schieberegler von 5 bis 200 Elemente. Wird zurückgesetzt, wenn du eigene Werte eingibst. + +- **Klein (5–20):** Gut zum Verstehen der Abläufe +- **Mittel (30–80):** Guter Kompromiss aus Übersicht und Realismus +- **Groß (100–200):** Zeigt das Skalierungsverhalten + +### Geschwindigkeit + +Schieberegler von 1 bis 100 — er represents die Verzögerung zwischen zwei Schritten in Millisekunden: + +- **1 (links):** ~1000 ms/Schritt — sehr langsam, zum Beobachten +- **50 (Mitte):** ~500 ms/Schritt — ausgewogen +- **100 (rechts):** ~10 ms/Schritt — sehr schnell + +Die tatsächliche Geschwindigkeit hängt auch von der Browser-Leistung und der Array-Größe ab. + +--- + +## 5. Steuerung + +| Button | Funktion | +|---|---| +| **⏮** | Einen Schritt zurück — zeigt die vorherige Operation | +| **▶** | Animation starten — läuft bis zum Ende oder bis Pause | +| **⏸** | Animation anhalten — kann mit ▶ fortgesetzt werden | +| **⏭** | Einen Schritt vor — führt genau eine Operation aus | +| **🔀** | Mischen — Fisher-Yates Shuffle auf das aktuelle Array | +| **↺** | Reset — setzt das Array in den Ausgangszustand zurück (vor dem Start der Animation) | +| **🌙/☀** | Theme wechseln — zwischen hellem und dunklem Modus | + +### Reset vs. Mischen + +- **Reset** stellt das Array so her, wie es beim letzten Start der Animation war. Das kann ein frisches Zufalls-Array sein oder deine eigenen Werte. +- **Mischen** führt einen Fisher-Yates-Shuffle auf das aktuelle Array aus — nützlich, um ein sortiertes Array wieder zu mischen und einen anderen Algorithmus zu testen. + +--- + +## 6. Tastaturkürzel + +Alle Funktionen sind auch ohne Maus bedienbar: + +| Taste | Funktion | +|---|---| +| `Space` / `K` | Play / Pause — Animation starten oder anhalten | +| `→` / `L` | Ein Schritt vor — nächste Operation | +| `←` / `J` | Ein Schritt zurück — vorherige Operation | +| `R` | Reset — Array zurücksetzen | +| `T` | Theme — zwischen hell und dunkel wechseln | +| `S` | Shuffle — Array mischen (Fisher-Yates) | + +**Hinweis:** Tastaturkürzel funktionieren nicht, wenn ein Eingabefeld oder Dropdown den Fokus hat. + +--- + +## 7. Farbcode + +Jede Farbe hat eine feste Bedeutung: + +| Farbe | Bedeutung | +|---|---| +| **Blau (Unsortiert)** | Normaler Zustand — Elemente die noch nicht sortiert sind | +| **Orange (Vergleich)** | Zwei Elemente werden gerade verglichen — ein Bogen verbindet sie | +| **Rot (Tausch)** | Zwei Elemente werden getauscht — ein roter Bogen zeigt die Tauschpartner | +| **Lila (Verschiebung)** | Ein Element wird verschoben (nicht getauscht) — z.B. bei Insertion Sort oder Merge Sort | +| **Grün (Sortiert/Fertig)** | Elemente an ihrer endgültigen Position — der Bereich wächst mit fortschreitender Sortierung | + +Ein **Bogen** über zwei Balken zeigt immer eine Beziehung zwischen den beiden Elementen: +- Oranger Bogen = Vergleich +- Roter Bogen = Tausch + +--- + +## 8. Statistik-Karten + +Unter dem Canvas zeigen vier Karten Echtzeit-Statistiken: + +| Karte | Beschreibung | +|---|---| +| **Zeit** | Vergangene Echtzeit seit Start der Animation in Millisekunden | +| **Schritte** | Anzahl der ausgeführten Schritte / Operationen | +| **Vergleiche** | Anzahl der Vergleichsoperationen (nur bei vergleichsbasierten Algorithmen) | +| **Tausche** | Anzahl der Tausch- oder Verschiebungsoperationen | + +**Hinweis:** Nicht-vergleichsbasierte Algorithmen (Counting, Radix, Bucket) zeigen bei „Vergleiche" keine sinnvollen Werte, da sie nicht Element-für-Element vergleichen. + +--- + +## 9. Speicher-Ansicht + +Bei einigen Algorithmen wird unterhalb des Haupt-Arrays ein zusätzlicher Speicherbereich visualisiert. Das hilft zu verstehen, wie Algorithmen temporären Platz benötigen: + +| Algorithmus | Speicher-Ansicht | +|---|---| +| **Merge Sort** | Zwei Hilfs-Arrays (blau und lila) — zeigt das Zusammenführen zweier sortierter Hälften | +| **Heap Sort** | Max-Heap als Baumdiagramm — zeigt die Hierarchie der Eltern-Kind-Beziehungen | +| **Tree Sort** | Binary Search Tree — zeigt die Baumstruktur die beim Sortieren aufgebaut wird | +| **Timsort** | Hilfs-Arrays — zeigt die verwalteten Runs und Merges | +| **Counting Sort** | Häufigkeitstabelle — zählt wie oft jeder Wert vorkommt | +| **Radix Sort** | Bucket-Verteilung — zeigt wie Ziffern in Buckets einsortiert werden | +| **Bucket Sort** | Bucket-Arrays — zeigt die Verteilung und Sortierung in den Buckets | + +--- + +## 10. URL-Parameter + +Der aktuelle Zustand (Algorithmus, Vorlage, Größe, Geschwindigkeit) wird automatisch in die URL geschrieben. Das bedeutet: + +- Du kannst die URL kopieren und an andere weitergeben — sie sehen dieselbe Konfiguration +- Beim Neuladen der Seite bleibt die Auswahl erhalten +- Du kannst Parameter auch manuell setzen + +**URL-Parameter:** + +``` +sorting_visualization.html?algo=quick&preset=random&size=50&speed=50 +``` + +| Parameter | Werte | Beschreibung | +|---|---|---| +| `algo` | `bubble`, `selection`, `insertion`, `cocktail`, `merge`, `heap`, `quick`, `quick3way`, `dualpivot`, `introsort`, `shell`, `tree`, `timsort`, `counting`, `radix`, `bucket`, `pancake`, `cycle`, `bogo`, `shuffle` | Ausgewählter Algorithmus | +| `preset` | `random`, `sorted`, `reversed`, `nearly`, `duplicates` | Datensatz-Vorlage | +| `size` | 5–200 | Array-Größe | +| `speed` | 1–100 | Geschwindigkeit | + +--- + +## 11. Warum sind Sortieralgorithmen wichtig? + +Sortieren ist eines der am intensivsten erforschten Probleme der Informatik — nicht aus akademischer Überheblichkeit, sondern weil es in der Praxis überall vorkommt: + +- **Datenbanken** müssen Abfrageergebnisse sortieren — bei Millionen von Datensätzen entscheidet der Algorithmus über Antwortzeiten +- **Betriebssysteme** verwalten Prioritätswarteschlangen und müssen Prozesse nach Dringlichkeit ordnen +- **Compiler** nutzen Sortieralgorithmen für die Optimierung (z.B. Register-Allokation) +- **Internetsuchen** beginnen oft mit sortierten Indices (z.B. B-Bäume in Datenbanken) +- **Empfehlungssysteme** sortieren Ergebnisse nach Relevanz + +### Der fundamentale Kompromiss + +Jeder Algorithmus repräsentiert einen anderen Kompromiss zwischen: + +- **Geschwindigkeit** — Wie viele Operationen braucht der Algorithmus? +- **Speicher** — Wie viel zusätzlichen Platz benötigt er? +- **Stabilität** — Behalten gleiche Werte ihre Reihenfolge? +- **Adaptivität** — Nutzt er vorhandene Ordnung aus? +- **Einfachheit** — Wie verständlich ist der Code? + +Wer diese Kompromisse versteht, kann für jede Situation die richtige Wahl treffen — sei es beim Sortieren von 100 Datensätzen auf einem Microcontroller oder 100 Millionen in einer Datenbank. + +### Was diese Visualisierung lehrt + +- **Bubble Sort** bei sortierten Daten: O(n) statt O(n²) — plötzliche Effizienz durch die „swapped"-Optimierung +- **Quick Sort** bei sortierten Daten mit erstem Pivot: O(n²) — warum naive Pivot-Wahl katastrophal sein kann +- **Timsort** bei fast-sortierten Daten: adaptiv und schnell — warum er in Python und Java Standard ist +- **3-Way Quick Sort** bei Duplikaten: O(n) statt O(n²) — warum Duplikate-Handling entscheidend ist +- **Fisher-Yates Shuffle**: Mischen ist O(n), Sortieren ist O(n log n) — ein Shuffle ist immer schneller als jede Sortierung + +--- + +## 12. Algorithmus-Übersicht + +### Eigenschaften + +| Symbol | Bedeutung | +|---|---| +| **Stabil** | Gleiche Werte behalten ihre ursprüngliche Reihenfolge bei | +| **Nicht stabil** | Die Reihenfolge gleicher Werte kann sich ändern | +| **In-place** | Sortiert im vorhandenen Array, braucht nur O(1) zusätzlichen Speicher | +| **O(n) Speicher** | Benötigt ein zusätzliches Hilfsarray proportional zur Eingabegröße | +| **Adaptiv** | Nutzt vorhandene Ordnung aus — bei fast sortierten Daten schneller | +| **Hybrid** | Kombiniert mehrere Strategien und wechselt je nach Situation | + +### Komplexitäts-Kategorien + +**O(n²) — Quadratisch** (einfache Verfahren) +Diese Algorithmen sind leicht zu verstehen, aber skalieren schlecht. Geeignet für kleine Datenmengen oder Lehrzwecke. + +- Bubble Sort — Stabil, In-place, adaptiv bei sortierten Daten +- Selection Sort — Nicht stabil, In-place, min. Schreiboperationen +- Insertion Sort — Stabil, In-place, adaptiv, der beste O(n²) +- Cocktail Shaker Sort — Stabil, In-place, löst das Schildkröten-Problem + +**O(n log n) — Quasi-linear** (effiziente Verfahren) +Die Standardwahl für allgemeine Sortierprobleme. Garantieren gute Leistung auch im schlimmsten Fall. + +- Merge Sort — Stabil, O(n) Speicher, garantiert O(n log n) +- Heap Sort — Nicht stabil, In-place, garantiert O(n log n) +- Quick Sort — Nicht stabil, In-place, O(n log n) im Durchschnitt +- 3-Way Quick Sort — Nicht stabil, In-place, O(n) bei vielen Duplikaten +- Dual-Pivot Quick Sort — Nicht stabil, In-place, Java Standard (JDK) +- Introsort — Nicht stabil, In-place, wechselt bei Rekursionstiefe zu Heap Sort +- Shell Sort — Nicht stabil, In-place, schneller als O(n²) durch Gap-Sequenz +- Tree Sort — Stabil (bei BST), O(n) Speicher, abhängig von Baumhöhe +- Timsort — Stabil, adaptiv, Hybrid aus Merge Sort und Insertion Sort, Python/Java Standard + +**O(n·k) — Linear** (nicht-vergleichsbasiert) +Diese Algorithmen nutzen spezielle Eigenschaften der Daten (z.B. Ganzzahl-Bereich) und können schneller sein als O(n log n). Funktionieren nicht mit beliebigen Vergleichbaren Werten. + +- Counting Sort — Stabil, O(n+k) mit k = Wertbereich, nur für Ganzzahlen +- Radix Sort — Stabil, O(n·k) mit k = Anzahl Ziffern, nur für Ganzzahlen +- Bucket Sort — Stabil, O(n+k) im Durchschnitt, adaptiv je nach Verteilung + +**Spezial** +Algorithmen mit besonderen Eigenschaften oder Anwendungsfällen. + +- Pancake Sort — Nicht stabil, In-place, nur Präfix-Flip-Operationen erlaubt +- Cycle Sort — Nicht stabil, In-place, min. Schreiboperationen (für Flash-Speicher) +- Bogo Sort — Nicht stabil, In-place, O(n·n!) erwartet, **auf 8 Elemente begrenzt** +- Fisher-Yates Shuffle — Stabil, In-place, O(n), uniform zufällig + +--- + +## Lizenz + +Dieses Projekt ist eine Open-Source-Lehr- und Lernressource. + +--- + +## Autor + +© 2026 Dieter Schlüter diff --git a/LICENSE b/LICENSE deleted file mode 100644 index bf7175e..0000000 --- a/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2026 dschlueter - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index b655eb0..7465c7f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,89 @@ -# sorting +# Sortier-Algorithmen Visualisierung -Visualisiert Sortier-Algorithmen in HTML mit Javascript \ No newline at end of file +Interaktive Visualisierung von 20 Sortieralgorithmen mit Schritt-für-Schritt-Darstellung, Speicher-Ansicht und Keyboard-Steuerung. + +**Datei:** `sorting_visualization.html` — Single-File, keine Abhängigkeiten, läuft direkt im Browser. + +[Online ansehen](sorting_visualization.html) · [Tests bestehen: 198/198](test_algorithms.js) + +--- + +## Algorithmus-Übersicht + +| Kategorie | Algorithmen | +|---|---| +| O(n²) | Bubble Sort, Selection Sort, Insertion Sort, Cocktail Shaker Sort | +| O(n log n) | Merge Sort, Heap Sort, Quick Sort, 3-Way Quick Sort, Dual-Pivot Quick Sort, Introsort, Shell Sort, Tree Sort, Timsort | +| Linear | Counting Sort, Radix Sort, Bucket Sort | +| Spezial | Pancake Sort, Cycle Sort, Bogo Sort, Fisher-Yates Shuffle | + +--- + +## Features + +- **20 Algorithmen** — vom klassischen Bubble Sort bis zum Fisher-Yates Shuffle +- **Speicher-Ansicht** — zeigt Hilfsdatenstrukturen bei Merge Sort, Heap Sort, Timsort, Counting/Radix/Bucket Sort +- **5 Datensatz-Presets** — Zufällig, Sortiert, Umgekehrt, Fast sortiert, Duplikate +- **Schritt-Navigation** — vor, zurück, Play/Pause +- **Keyboard-Steuerung** — alle Funktionen auch ohne Maus bedienbar +- **URL-State** — Auswahl bleibt beim Neuladen erhalten +- **Mobile optimiert** — Touch-Support, zoom-resistent +- **Hell/Dunkel-Modus** — per Button oder `T` +- **Barrierefreiheit** — ARIA-Labels, Screen-Reader-Ankündigungen + +--- + +## Schnellstart + +1. `sorting_visualization.html` im Browser öffnen +2. Algorithmus wählen → Start mit `Space` +3. Oder: Play-Button drücken + +--- + +## Tastaturkürzel + +| Taste | Funktion | +|---|---| +| `Space` / `K` | Play / Pause | +| `→` / `L` | Ein Schritt vor | +| `←` / `J` | Ein Schritt zurück | +| `R` | Reset | +| `T` | Theme wechseln | +| `S` | Mischen (Fisher-Yates) | + +--- + +## Tests + +```bash +node test_algorithms.js +``` + +Alle 198 Tests müssen bestehen. + +--- + +## Dateien + +``` +sorting_visualization.html # Hauptprogramm (Single-File) +test_algorithms.js # Node.js Test-Suite +.gitignore # Git-Konfiguration +README.md # Dieses Dokument +``` + +--- + +## Entwicklung + +- **Kein Build-Schritt** — pure HTML/JS/CSS +- **Keine externen Abhängigkeiten** — läuft offline +- **Externe CDN** (optional, für Icons): Lucide Icons, Tailwind CSS +- **Version** — wird automatisch via `pre-commit`-Hook erhöht + +--- + +## Autor + +© 2026 Dieter Schlüter diff --git a/sorting_visualization.html b/sorting_visualization.html new file mode 100644 index 0000000..bdc188a --- /dev/null +++ b/sorting_visualization.html @@ -0,0 +1,2986 @@ + + + + + + + Sortier-Algorithmen Visualisierung + + + + + + + + + + + + + + + +
+ + +
+
+
+

+ Sortier-Algorithmen v0.2.18 +

+

Interaktive Visualisierung mit schrittweiser Animation

+
+
+ +
+
+ + +
+ + + + + +
+ + +
+
 
+
 
+
+ + +
+ + + + +
+ + +
+
+
+
+ 0 / 0 +
+ + +
+
+
0
+
+ Vergleiche +
+
Wie oft zwei Elemente miteinander verglichen wurden.
+
+
+
0
+
+ Tausche +
+
Wie oft zwei Elemente ihre Plätze getauscht haben.
+
+
+
0
+
+ Verschiebungen +
+
Wie oft ein Wert auf eine Position geschrieben oder verschoben wurde.
+
+
+
0
+
+ Schritt +
+
Der aktuell ausgeführte Visualisierungsschritt.
+
+
+
0 ms
+
+ Zeit +
+
Vergangene Echtzeit seit Start der Animation.
+
+
+ +
+
+ + +
+ + + Über die Algorithmen + + +
+ +

Speicher-Ansicht: Bei Tree Sort, Merge Sort, Timsort, Heap Sort, Counting Sort, Radix Sort und Bucket Sort wird der Arbeitsspeicher unterhalb des Arrays visualisiert. Sie sehen genau, wo Daten zwischengespeichert werden — ob als Baumstruktur (BST, Heap), Hilfs-Arrays (Merge), Häufigkeitstabelle (Counting) oder Bucket-Verteilung (Radix, Bucket).

+ + +
+

Legende der Eigenschaften

+
+
Stabil Gleiche Werte behalten ihre ursprüngliche Reihenfolge bei.
+
Nicht stabil Die Reihenfolge gleicher Werte kann sich ändern.
+
In-place Sortiert im vorhandenen Array, braucht nur O(1) zusätzlichen Speicher.
+
O(n) Speicher Benötigt ein zusätzliches Hilfsarray proportional zur Eingabegröße.
+
Adaptiv Nutzt vorhandene Ordnung aus — bei fast sortierten Daten schneller.
+
Hybrid Kombiniert mehrere Strategien und wechselt je nach Situation.
+
O(n²) Zeitkomplexität — beschreibt, wie die Laufzeit mit der Eingabegröße wächst. O(n²) = quadratisch (langsam bei großen Daten), O(n log n) = quasi-linear (effizient), O(n+k) = linear (schnellstmöglich). Stehen zwei Werte (z.B. „O(n²) worst · O(n) best“), beschreibt der erste den schlechtesten, der zweite den besten Fall.
+
+
+ +
+

Farbcode der Visualisierung

+
+
Orange = Vergleich
+
Rot = Tausch
+
Lila = Verschiebung
+
Grün = Sortiert / Fertig
+
Blau = Unsortiert
+
+
+ + +
+

O(n²) — Einfache Verfahren

+
+ +
+

Bubble Sort

+
+ Stabil + In-place + O(n²) +
+

Funktionsweise: Durchläuft das Array wiederholt von links nach rechts und vergleicht jeweils zwei benachbarte Elemente. Ist das linke Element größer als das rechte, werden sie getauscht. Nach jedem vollständigen Durchlauf „blubbert" das größte noch unsortierte Element an seine endgültige Position am Ende. Das wird so lange wiederholt, bis ein Durchlauf ohne Tausch stattfindet.

+

Darstellung: Ein orange leuchtendes Paar wandert von links nach rechts — ein geschwungener Bogen über den Balken verbindet die beiden verglichenen Elemente und macht die Paarung auf einen Blick klar. Wird getauscht, werden beide Balken rot und der Bogen wechselt ebenfalls die Farbe. Mit jedem Durchlauf wächst der bereits sortierte Bereich am rechten Rand: er ist grünlich hinterlegt und dehnt sich Schritt für Schritt aus. Unter jedem Balken zeigt eine kleine Zahl den aktuellen Wert. Die Zeile über dem Canvas benennt den aktuellen Schritt (z.B. „Vergleiche arr[3]=42.1 mit arr[4]=17.5").

+

Wann einsetzen: Hauptsächlich zu Lehrzwecken, da er der intuitivste Sortieralgorithmus ist. Bei fast sortierten Daten kann er mit der „swapped"-Optimierung in O(n) terminieren. Für produktiven Einsatz aber zu langsam — Insertion Sort ist in derselben Komplexitätsklasse stets überlegen.

+
+ +
+

Selection Sort

+
+ Nicht stabil + In-place + O(n²) +
+

Funktionsweise: Teilt das Array gedanklich in einen sortierten (links) und unsortierten (rechts) Bereich. In jedem Schritt wird das Minimum des unsortierten Bereichs gesucht und mit dem ersten unsortierten Element getauscht. So wächst der sortierte Bereich um eins pro Durchlauf.

+

Darstellung: Ein oranger Bogen verbindet den aktuellen Minimum-Kandidaten mit dem nächsten Vergleichselement. Wird ein kleineres Element gefunden, springt der Bogen dorthin. Am Ende der Suche setzt ein roter Tausch (roter Bogen) das Minimum an die linke Grenze des unsortierten Bereichs. Die linke Seite des Arrays ist grünlich hinterlegt und wächst pro Durchlauf um genau einen Balken. Kleine Wertemarken unter den Balken erleichtern das Ablesen.

+

Wann einsetzen: Nützlich wenn die Anzahl der Schreiboperationen (Swaps) minimiert werden soll — Selection Sort führt maximal O(n) Tauschvorgänge aus, unabhängig von den Daten. Relevant z.B. bei Flash-Speicher mit begrenzten Schreibzyklen. Für allgemeine Zwecke ist Insertion Sort vorzuziehen.

+
+ +
+

Insertion Sort

+
+ Stabil + In-place + Adaptiv + O(n²) worst · O(n) best +
+

Funktionsweise: Arbeitet wie das Sortieren von Spielkarten auf der Hand: Nimmt das nächste Element aus dem unsortierten Bereich und schiebt es im bereits sortierten Bereich so lange nach links, bis die richtige Position gefunden ist. Alle größeren Elemente werden dabei um eine Position nach rechts verschoben.

+

Darstellung: Ein oranger Bogen verbindet das einzufügende Element mit seinem linken Nachbarn. Ist es kleiner, wird es lila nach links verschoben — der Bogen wandert mit. Die lilafarbenen Verschiebungen zeigen, wie das Element schrittweise durch den bereits sortierten (grünlich hinterlegten) Bereich rutscht, bis es seine korrekte Position findet. Kleine Wertemarken unter den Balken helfen beim Verfolgen der Werte.

+

Wann einsetzen: Der beste O(n²)-Algorithmus in der Praxis. Bei fast sortierten Daten läuft er nahezu in O(n). Wird oft als Basis-Algorithmus in hybriden Verfahren eingesetzt (z.B. Timsort, Introsort), die bei kleinen Teilarrays (n < 16) auf Insertion Sort umschalten, weil sein geringer Overhead den asymptotischen Nachteil wettmacht.

+
+ +
+

Cocktail Shaker Sort

+
+ Stabil + In-place + O(n²) +
+

Funktionsweise: Eine Variante von Bubble Sort, die abwechselnd in beide Richtungen durchläuft — erst von links nach rechts (große Elemente aufsteigen lassen), dann von rechts nach links (kleine Elemente absinken lassen). Die Grenzen des unsortierten Bereichs werden dabei von beiden Seiten eingeengt.

+

Darstellung: Ein oranger Bogen wandert abwechselnd nach rechts und nach links — bei einem Tausch wechselt er rot. Links und rechts wächst gleichzeitig je ein grünlich hinterlegter sortierter Bereich, der den unsortierten Mittelteil von beiden Seiten einengt. Die Bogenrichtung macht den Wechsel der Durchlaufrichtung unmittelbar sichtbar.

+

Wann einsetzen: Löst das sogenannte „Schildkröten-Problem" von Bubble Sort: Kleine Werte am Ende des Arrays wandern bei normalem Bubble Sort nur eine Position pro Durchlauf nach vorne. Durch den Rückwärtsdurchlauf werden sie viel schneller an die richtige Position befördert. Besonders effektiv bei Arrays, die „fast sortiert" sind, aber einzelne Ausreißer in beide Richtungen haben.

+
+ + +
+
+ + +
+

O(n log n) — Effiziente Verfahren

+
+ +
+

Merge Sort

+
+ Stabil + O(n) Speicher + O(n log n) garantiert +
+

Funktionsweise: Klassisches Divide-and-Conquer: Das Array wird rekursiv in zwei Hälften geteilt, bis nur noch Einzelelemente übrig sind. Dann werden die sortierten Hälften schrittweise wieder zusammengeführt (gemergt), indem jeweils das kleinere der beiden vordersten Elemente übernommen wird. Dieser Merge-Schritt ist der Kern des Algorithmus.

+

Darstellung: Das Phase-Label über dem Canvas zeigt „Merge", sobald zwei Hälften zusammengeführt werden. Ein oranger Bogen verbindet die aktuell verglichenen Elemente aus den beiden Hälften; blaue Klammern am oberen Rand markieren den aktiven Teilbereich. Unterhalb erscheint die Speicher-Ansicht mit den beiden Hilfs-Arrays: links (blau) und rechts (lila) — ein hervorgehobener Balken zeigt den aktuellen Lesezeiger. Lila Verschiebungen im Haupt-Array zeigen, wohin die Elemente geschrieben werden. Kleine Wertemarken unter den Balken helfen, den Überblick zu behalten.

+

Wann einsetzen: Ideal wenn eine garantierte O(n log n)-Laufzeit und Stabilität erforderlich sind — z.B. beim Sortieren von Datensätzen mit mehreren Schlüsseln oder bei verketteten Listen (dort ohne zusätzlichen Speicher möglich). Bildet die Basis von Pythons Timsort und Javas Arrays.sort() für Objekte. Der zusätzliche O(n)-Speicherbedarf ist der Hauptnachteil gegenüber Quick Sort.

+
+ +
+

Heap Sort

+
+ Nicht stabil + In-place + O(n log n) garantiert +
+

Funktionsweise: Nutzt die Heap-Datenstruktur (Max-Heap), die direkt im Array repräsentiert wird. Phase 1 (Build-Heap): Das Array wird in O(n) in einen Max-Heap umgewandelt, bei dem jeder Elternknoten größer ist als seine Kinder. Phase 2 (Extract): Das Maximum (Wurzel) wird wiederholt mit dem letzten Element getauscht und der Heap um eins verkleinert. Dann wird die Heap-Eigenschaft durch „Heapify" (Absinken) wiederhergestellt.

+

Darstellung: Das Phase-Label wechselt sichtbar von „Heap aufbauen" zu „Extrahieren". Ein oranger Bogen verbindet den jeweils verglichenen Eltern- und Kind-Knoten im Array — die weiten Sprünge machen die Baumstruktur im flachen Array erlebbar. Beim Extrahieren wächst der grünlich hinterlegte sortierte Bereich von rechts. Unterhalb erscheint der Max-Heap als Baumdiagramm: Orange hervorgehobene Knoten zeigen den aktuellen Vergleich, der Baum schrumpft nach jedem Extract-Schritt. Kleine Wertemarken unter den Balken helfen, Eltern-Kind-Beziehungen nachzuvollziehen.

+

Wann einsetzen: Bietet die einzigartige Kombination aus garantierter O(n log n)-Laufzeit und O(1)-Speicher — also echtes In-place ohne zusätzlichen Speicher. Ideal für speicherkritische Systeme oder als Fallback in hybriden Algorithmen (z.B. Introsort wechselt auf Heap Sort, wenn Quick Sorts Rekursionstiefe zu groß wird). In der Praxis langsamer als Quick Sort wegen schlechter Cache-Lokalität (springt weit im Array).

+
+ +
+

Quick Sort

+
+ Nicht stabil + In-place + O(n log n) avg · O(n²) worst +
+

Funktionsweise: Ebenfalls Divide-and-Conquer, aber anders als Merge Sort: Zuerst wird ein Pivot-Element gewählt. Dann wird das Array so umgeordnet (partitioniert), dass alle Elemente kleiner als der Pivot links stehen und alle größeren rechts. Der Pivot ist danach an seiner endgültigen Position. Dieser Vorgang wird rekursiv auf die beiden Teilarrays angewendet.

+

Darstellung: Das Phase-Label zeigt „Partition". Das Pivot-Element (letztes Element des Teilarrays) trägt einen weißen Rahmen als Markierung. Blaue Klammern am oberen Rand begrenzen den aktiven Teilbereich. Orange Bögen verbinden den aktuellen Vergleichspartner mit dem Pivot; rote Bögen markieren Tausche. Sobald der Pivot an seine endgültige Position gesetzt wird, beginnt das Muster in einem kleineren Teilbereich von vorn — so wird der Divide-and-Conquer-Charakter visuell greifbar.

+

Wann einsetzen: In der Praxis meistens der schnellste vergleichsbasierte Algorithmus, weil er hervorragende Cache-Lokalität hat (arbeitet sequentiell im Speicher). Wird in C's qsort(), Javas Arrays.sort() für Primitives und vielen Standard-Libraries eingesetzt. Die O(n²)-Worst-Case-Laufzeit tritt bei ungünstiger Pivot-Wahl auf (z.B. bereits sortiertes Array mit erstem Element als Pivot). Randomisierte oder Median-of-Three-Pivot-Wahl eliminiert dieses Problem praktisch.

+
+ +
+

3-Way Quick Sort

+
+ Nicht stabil + In-place + Duplikateneffizient + O(n log n) avg · O(n) bei vielen Duplikaten +
+

Funktionsweise: Auch bekannt als „Dutch National Flag"-Algorithmus (Dijkstra). Im Gegensatz zum klassischen Quick Sort, der zwei Bereiche erzeugt (< Pivot und > Pivot), teilt diese Variante das Array in drei Bereiche: Elemente kleiner als der Pivot (links), gleich dem Pivot (Mitte) und größer als der Pivot (rechts). Alle Duplikate des Pivots landen sofort in der Mitte und werden nie wieder verglichen. Dadurch wird das Problem vieler gleicher Werte elegant gelöst — klassischer Quick Sort degeneriert dabei zu O(n²).

+

Darstellung: Drei farbige Hintergrundbereiche machen die Dreiteilung sichtbar: links (blau) Elemente kleiner als Pivot, Mitte (orange) gleich dem Pivot, rechts (lila) größer als Pivot. Orange Bögen zeigen Vergleiche gegen den Pivot; rote Bögen markieren Tausche, die Elemente in den richtigen Bereich befördern. Der mittlere Gleichheits-Bereich wächst bei Duplikaten spürbar schnell — er wird bei der Rekursion komplett übersprungen.

+

Wann einsetzen: Immer wenn die Daten viele Duplikate enthalten — z.B. beim Sortieren nach Ländercodes, Booleschen Werten, Altersgruppen oder Bewertungsstufen. Klassischer Quick Sort braucht bei n identischen Elementen O(n²), 3-Way Quick Sort nur O(n). Die Median-of-Three-Pivot-Wahl verhindert zusätzlich den Worst Case bei bereits sortierten Daten.

+
+ +
+

Dual-Pivot Quick Sort

+
+ Nicht stabil + In-place + Java Standard + O(n log n) avg +
+

Funktionsweise: Entwickelt von Vladimir Yaroslavskiy (2009), seit Java 7 der Standard-Algorithmus für Arrays.sort() bei primitiven Typen. Verwendet zwei Pivot-Elemente (P1 ≤ P2) und teilt das Array in drei Bereiche: Elemente < P1 (links), Elemente zwischen P1 und P2 (Mitte), Elemente > P2 (rechts). Die drei Bereiche werden dann rekursiv sortiert. Durch die feinere Aufteilung werden die Teilarrays kleiner als bei einfachem Quick Sort.

+

Darstellung: Beide Pivot-Elemente (P1 links, P2 rechts) tragen einen weißen Rahmen. Blaue Klammern markieren den aktiven Teilbereich. Drei farbige Hintergrundbereiche entstehen schrittweise: links (blau) kleiner P1, Mitte (orange) zwischen P1 und P2, rechts (lila) größer P2. Orange Bögen zeigen Vergleiche, rote Bögen die Tausche in die richtigen Bereiche. Dass der aktive Bereich sich durch die Dreiteilung deutlich schneller verkleinert als beim klassischen Quick Sort, ist am Fortschrittsbalken ablesbar.

+

Wann einsetzen: Der Industriestandard in Java für primitive Typen — in der Praxis oft 10–20 % schneller als klassischer Quick Sort, weil die feinere Partitionierung die Cache-Ausnutzung verbessert. Besonders effektiv bei großen Arrays mit gleichmäßig verteilten Werten. Die Implementierung ist komplexer als klassischer Quick Sort, lohnt sich aber bei performancekritischen Anwendungen.

+
+ +
+

Introsort

+
+ Nicht stabil + In-place + Hybrid + C++/Rust Standard + O(n log n) garantiert +
+

Funktionsweise: Ein hybrider Algorithmus (David Musser, 1997), der das Beste dreier Welten kombiniert: Er startet als Quick Sort mit Median-of-Three-Pivot für die durchschnittlich beste Performance. Überschreitet die Rekursionstiefe 2·log₂(n), wechselt er auf Heap Sort — das garantiert O(n log n) auch im Worst Case. Für kleine Teilarrays (≤ 16 Elemente) wird Insertion Sort verwendet, da dieser bei wenigen Elementen wegen geringerem Overhead schneller ist. So wird Quick Sorts O(n²)-Schwäche eliminiert, ohne auf seine Durchschnitts-Performance zu verzichten.

+

Darstellung: Das Phase-Label über dem Canvas verrät stets, welche Strategie gerade aktiv ist: „Quick Sort" bei der Partitionierung (Pivot mit weißem Rahmen, blaue Bereichsklammern, orange/rote Bögen), „Insertion Sort" bei kleinen Teilarrays ≤ 16 (lila Verschiebungen benachbarter Elemente ohne Pivot), „Heap Sort (Fallback)" wenn die Rekursionstiefe überschritten wird (weite Sprünge, kein Pivot-Marker). Dieser automatische Strategiewechsel, der in der Phase-Anzeige direkt ablesbar ist, macht Introsort visuell einzigartig unter allen hier gezeigten Algorithmen.

+

Wann einsetzen: Der Standard-Algorithmus in C++ (std::sort), Rust (slice::sort_unstable) und vielen weiteren Systemen. Introsort ist die Antwort auf die Frage „Welchen Algorithmus nehme ich, wenn ich nicht weiß, wie die Daten aussehen?" — er ist universell einsetzbar mit garantierter O(n log n)-Laufzeit und minimalem Speicherbedarf. Zusammen mit Timsort (Python, Java für Objekte) deckt er die beiden wichtigsten Industrie-Standards ab.

+
+ +
+

Shell Sort

+
+ Nicht stabil + In-place + Adaptiv + O(n log²n) mit Knuth +
+

Funktionsweise: Eine Verallgemeinerung von Insertion Sort. Statt nur benachbarte Elemente zu vergleichen, werden zunächst weit auseinanderliegende Elemente verglichen und sortiert (mit großem „Gap"). Der Gap wird schrittweise verkleinert (hier nach Knuth: ..., 40, 13, 4, 1). In jeder Runde wird ein Insertion Sort auf die Elemente mit dem jeweiligen Abstand ausgeführt. Beim letzten Durchlauf (Gap=1) ist es ein normaler Insertion Sort — aber auf fast sortierte Daten, was ihn extrem schnell macht.

+

Darstellung: Oben rechts im Canvas zeigt eine Beschriftung den aktuellen Gap-Wert. Zu Beginn überspannen die orangen Bögen weite Distanzen — ein großer Gap bedeutet, dass weit auseinanderliegende Balken verglichen werden. Mit jedem Durchlauf schrumpft der Gap (und damit die Bogenlänge) sichtbar: 40 → 13 → 4 → 1. Im letzten Durchlauf (Gap=1) sind die Bögen kurz wie bei Insertion Sort — aber die Daten sind bereits so gut vorsortiert, dass kaum noch lila Verschiebungen nötig sind.

+

Wann einsetzen: Ideal wenn ein einfacher, rekursionsfreier Algorithmus benötigt wird, der deutlich besser als O(n²) performt. Kein Stack-Overhead, wenig Code, exzellente Cache-Lokalität. Wird häufig in Embedded Systems und in der Linux-Kernel-Implementierung verwendet. Die exakte Komplexität hängt von der Gap-Sequenz ab — kein Beweis für eine optimale Folge ist bekannt, was Shell Sort theoretisch besonders interessant macht.

+
+ + +
+

Tree Sort (BST)

+
+ Stabil (bei gleichen rechts) + O(n) Speicher + Baumbasiert + O(n log n) avg · O(n²) worst +
+

Funktionsweise: Baut einen binären Suchbaum (BST) auf, indem jedes Array-Element nacheinander eingefügt wird. Im BST gilt: Alle Werte im linken Teilbaum eines Knotens sind kleiner, alle im rechten sind größer oder gleich. Zum Einfügen wird der Baum von der Wurzel abwärts durchlaufen — bei jedem Knoten wird entschieden, ob links oder rechts weitergesucht wird. Nach dem Aufbau werden die Elemente durch eine In-Order-Traversierung (links → Knoten → rechts) in sortierter Reihenfolge zurück ins Array geschrieben.

+

Darstellung: Oben wird das aktuelle Array-Element lila hervorgehoben, das gerade in den Baum eingefügt wird. Unterhalb wächst der Binäre Suchbaum Knoten für Knoten — der orange leuchtende Pfad zeigt die Suchroute von der Wurzel bis zur Einfügeposition. In der zweiten Phase (In-Order-Traversal) werden die Knoten nacheinander orange markiert und ihre Werte lila ins Haupt-Array zurückgeschrieben. Die Schritt-Erklärung über dem Canvas gibt bei jeder Verschiebung die genaue Zielposition an.

+

Wann einsetzen: Zeigt den fundamentalen Zusammenhang zwischen Datenstrukturen und Sortieren — ein BST ist im Kern ein „lebendiger" Sortieralgorithmus. Bei balancierten Daten O(n log n), aber bei bereits sortierten Eingaben degeneriert der Baum zu einer linearen Kette → O(n²). Selbstbalancierende Bäume (AVL, Rot-Schwarz) lösen dieses Problem, sind aber komplexer. In der Praxis wird Tree Sort selten direkt verwendet, aber das Verständnis ist essentiell für Datenbanken (B-Bäume), Sets und Maps.

+
+ +
+

Timsort

+
+ Stabil + Adaptiv + Hybrid + O(n) Speicher + O(n log n) garantiert +
+

Funktionsweise: Vereint das Beste aus Insertion Sort und Merge Sort. Phase 1: Das Array wird in „Runs" (Teilstücke der Größe 32) aufgeteilt und jeder Run mit Insertion Sort sortiert — das ist bei kleinen Datenmengen schneller als Merge Sort wegen geringerem Overhead. Phase 2: Die sortierten Runs werden dann bottom-up mit einem optimierten Merge-Verfahren zusammengeführt, wobei die Run-Größe in jeder Runde verdoppelt wird (32 → 64 → 128 → ...). Die echte Timsort-Implementierung erkennt zusätzlich natürlich vorhandene sortierte Teilstücke (natürliche Runs) und nutzt sie aus.

+

Darstellung: Das Phase-Label wechselt zwischen den beiden Phasen: In Phase 1 sehen Sie nur das Haupt-Array mit kurzen orangen Bögen und lila Verschiebungen innerhalb kleiner 32-Elemente-Blöcke (Insertion Sort). Dünne vertikale Linien im Balkendiagramm markieren die Run-Grenzen und machen sichtbar, wie das Array in sortierte Blöcke aufgeteilt wird. Sobald Phase 2 beginnt, erscheint die Speicher-Ansicht mit den Hilfs-Arrays (blau links, lila rechts) — orangere Bögen über größere Distanzen zeigen, wie die Blöcke von 32 auf 64, 128 usw. anwachsen.

+

Wann einsetzen: Der Standard-Sortieralgorithmus in Python (seit 2002), Java (Arrays.sort für Objekte), Android, Swift und V8 (JavaScript-Engine von Chrome). Wurde von Tim Peters speziell für reale Daten entwickelt, die oft bereits teilweise sortiert sind. Bei fast sortierten Daten läuft Timsort nahezu in O(n), bei zufälligen Daten zuverlässig in O(n log n). Wenn man nur einen einzigen Algorithmus kennen sollte, der „in der echten Welt" verwendet wird, ist es Timsort.

+
+ +
+
+ + + +
+

O(n·k) — Nicht-vergleichsbasiert

+
+ +
+

Counting Sort

+
+ Stabil + O(n + k) Speicher + O(n + k) +
+

Funktionsweise: Durchbricht die theoretische Untergrenze O(n log n) für vergleichsbasierte Verfahren, indem er gar nicht vergleicht. Stattdessen wird ein Hilfsarray (Größe k = Wertebereich) angelegt und für jeden Wert gezählt, wie oft er vorkommt. Aus den Häufigkeiten lässt sich direkt die sortierte Reihenfolge ableiten: Jeder Wert wird entsprechend seiner Häufigkeit zurückgeschrieben.

+

Darstellung: Oben werden Elemente lila hervorgehoben, wenn sie gezählt bzw. zurückgeschrieben werden — da Counting Sort nicht vergleicht, gibt es keine orangen Bögen. Unterhalb erscheint das Häufigkeits-Array als grünes Balkendiagramm: Jeder Balken repräsentiert einen Wert, die Höhe zeigt die Häufigkeit. Der aktuell bearbeitete Wert leuchtet lila. Beim Zurückschreiben schrumpfen die Häufigkeitsbalken, während das Haupt-Array von links nach rechts sortiert befüllt wird. Kleine Wertemarken unter den Balken zeigen die ganzzahligen Werte, auf die die Eingabe intern gerundet wird.

+

Wann einsetzen: Extrem schnell wenn der Wertebereich k klein ist relativ zu n (z.B. Noten 1–6, Alter 0–150, Buchstaben). Wird linear langsamer wenn k wächst — bei k ≫ n ist Counting Sort ineffizienter als vergleichsbasierte Verfahren. Dient als stabile Unterroutine in Radix Sort. Kann nur ganzzahlige oder diskrete Werte sortieren.

+
+ +
+

Radix Sort (LSD)

+
+ Stabil + O(n + k) Speicher + O(d · (n + k)) +
+

Funktionsweise: Sortiert Zahlen stellenweise, beginnend bei der niederwertigsten Stelle (Least Significant Digit, LSD). In jeder Runde wird ein stabiler Sortieralgorithmus (hier Counting Sort mit Basis k=10) auf eine einzelne Dezimalstelle angewendet. Durch die Stabilität bleiben die Ergebnisse vorheriger Runden erhalten. Nach d Runden (d = Anzahl der Stellen der größten Zahl) ist das gesamte Array sortiert.

+

Darstellung: Das Phase-Label zeigt die aktuelle Stelle und Richtung, z.B. „Stelle 1 — Verteilen" und „Stelle 1 — Sammeln". Oben werden Elemente lila markiert (kein Vergleich → kein Bogen). Unterhalb zeigt die Speicher-Ansicht die 10 Radix-Buckets (Ziffern 0–9) als Spalten mit gestapelten Blöcken — jeder Block enthält den Zahlenwert. Der aktive Bucket leuchtet lila. Pro Stellendurchlauf füllen sich die Buckets und werden anschließend der Reihe nach ins Array zurückgeschrieben. Da intern mit ganzen Zahlen gearbeitet wird, zeigen die Wertemarken gerundete Werte.

+

Wann einsetzen: Schlägt vergleichsbasierte Verfahren wenn die Zahl der Stellen d konstant oder klein ist — z.B. Postleitzahlen (5-stellig), IP-Adressen, Telefonnummern, Datums-Timestamps. Die effektive Laufzeit ist dann O(n). Kann auch auf Strings gleicher Länge angewandt werden (zeichenweises Sortieren). Nicht geeignet für Fließkommazahlen oder stark variierende Schlüssellängen.

+
+ +
+

Bucket Sort

+
+ Stabil (bei stabilem Sub-Sort) + O(n + k) Speicher + O(n + k) avg · O(n²) worst +
+

Funktionsweise: Teilt den Wertebereich in eine Anzahl gleich großer „Eimer" (Buckets) auf. Jedes Element wird anhand seines Wertes in den passenden Eimer einsortiert. Dann wird jeder Eimer einzeln sortiert (hier mit Insertion Sort, da die Eimer typischerweise klein sind). Zuletzt werden die Eimer der Reihe nach zusammengefügt. Die Anzahl der Buckets wird hier als √n gewählt.

+

Darstellung: Oben wird jedes Element lila markiert, wenn es in einen Bucket verteilt oder ins Array zurückgeschrieben wird (kein Vergleich → kein Bogen). Unterhalb zeigt die Speicher-Ansicht die k Buckets als Rahmen mit Balken darin — die Balkenhöhe entspricht dem Wert des Elements. Der aktive Bucket leuchtet lila. Sie sehen, wie sich die Elemente auf die Buckets verteilen, und beim Zurückschreiben, wie ein gleichmäßig befülltes Array entsteht. Kleine Wertemarken unter den Balken zeigen Fließkommazahlen, die direkt in Buckets einsortiert werden.

+

Wann einsetzen: Am effizientesten wenn die Eingabedaten gleichmäßig über den Wertebereich verteilt sind — dann enthält jeder Bucket nur wenige Elemente und der Gesamt-Aufwand ist O(n). Ideal für Fließkommazahlen im Bereich [0, 1), Prüfungsnoten, Messwerte mit bekanntem Bereich. Wenn alle Elemente in denselben Bucket fallen (z.B. viele identische Werte), degeneriert Bucket Sort zum Sub-Sort-Algorithmus. Konzeptionell das intuitivste nicht-vergleichsbasierte Verfahren — man denkt automatisch an Schubladen oder Fächer.

+
+ +
+
+ + +
+

Spezial — Ungewöhnliche Verfahren

+
+ +
+

Pancake Sort

+
+ Nicht stabil + In-place + O(n²) +
+

Funktionsweise: Die einzige erlaubte Operation ist ein „Präfix-Flip": Man schiebt einen Pfannenwender an einer beliebigen Stelle unter den Pfannkuchenstapel und dreht alles darüber um. Das Verfahren arbeitet von hinten nach vorne: In jedem Schritt wird das Maximum im unsortierten Bereich gefunden. Dann wird zuerst ein Flip bis zu diesem Maximum ausgeführt (Maximum landet ganz vorne), dann ein Flip bis zur Endposition (Maximum landet an der richtigen Stelle). So wandert pro Runde ein Element an seine endgültige Position.

+

Darstellung: Zuerst wandert ein oranger Bogen durch den unsortierten Bereich auf der Suche nach dem Maximum. Dann folgt ein spektakulärer Flip: Mehrere Balken werden gleichzeitig rot — ein ganzer Präfix des Arrays wird auf einmal umgekehrt. Zwei solcher Flips pro Runde erzeugen das charakteristische Doppel-Umkehrmuster: erst bringt ein Flip das Maximum nach ganz links, dann schiebt ein zweiter es an seine Zielposition am rechten Ende des unsortierten Bereichs.

+

Wann einsetzen: Löst ein berühmtes kombinatorisches Problem: „Wie viele Flips braucht man im schlimmsten Fall, um n Pfannkuchen zu sortieren?" (Pancake-Zahl). Bill Gates' erste wissenschaftliche Veröffentlichung (1979) bewies eine obere Schranke dafür. Praxisrelevant in der Bioinformatik: Genom-Umordnungen (Inversionen von DNA-Segmenten) entsprechen exakt Pancake-Flips. Auch in der Robotik relevant, wenn ein Roboter nur „Umdreh"-Operationen ausführen kann. Visuell besonders eindrucksvoll, weil die Flips ganze Abschnitte auf einmal umkehren.

+
+ +
+

Cycle Sort

+
+ Nicht stabil + In-place + Min. Schreibops + O(n²) +
+

Funktionsweise: Basiert auf der Zerlegung einer Permutation in Zyklen. Für jedes Element wird berechnet, wo es in der sortierten Reihenfolge stehen müsste (durch Zählen aller kleineren Elemente). Dann wird es dorthin verschoben, wobei das verdrängte Element aufgenommen und ebenfalls an seine korrekte Position gebracht wird — bis der Zyklus sich schließt (man wieder am Startpunkt ankommt). Jedes Element wird dabei höchstens einmal an seine endgültige Position geschrieben.

+

Darstellung: Ein langer Scan: Viele orange Bögen erscheinen nacheinander, während der Algorithmus zählt, wie viele Elemente kleiner als das aktuelle sind. Dann folgt eine einzelne lila Verschiebung — das Element springt direkt an seine berechnete Zielposition, ohne einen Umweg. Dieser Wechsel aus vielen kurzen Bögen (Zählphase) und einem einzigen punktuellen Schreibvorgang macht die Eigenheit von Cycle Sort unmittelbar erlebbar: O(n²) Vergleiche für minimale Schreiboperationen. Bereits an ihrer Zielposition stehende Elemente sind grünlich hinterlegt; die Wertemarken unter den Balken helfen, die berechneten Zielpositionen nachzuvollziehen.

+

Wann einsetzen: Der einzige Sortieralgorithmus, der die theoretisch minimale Anzahl an Schreiboperationen garantiert. Jedes Element wird höchstens einmal geschrieben (statt mehrfach verschoben wie bei anderen Algorithmen). Essenziell bei EEPROM oder Flash-Speicher, wo jeder Schreibvorgang den Speicher abnutzt und die Lebensdauer verkürzt. Auch nützlich zum Erkennen, ob eine Permutation aus einem einzigen Zyklus besteht. Die vielen Vergleiche (O(n²)) sind der Preis für die minimalen Schreiboperationen.

+
+ +
+

Bogo Sort

+
+ Nicht stabil + In-place + Max. 8 Elemente + O(n · n!) erwartet +
+

Funktionsweise: Der „dümmste" Sortieralgorithmus: Das Array wird zufällig gemischt (Fisher-Yates-Shuffle), dann wird geprüft, ob es jetzt zufällig sortiert ist. Wenn nicht, wird erneut gemischt. Das wird wiederholt, bis das Array durch Zufall in der richtigen Reihenfolge landet. Es gibt keine Garantie, dass das jemals passiert — im Erwartungswert braucht man n! Versuche (bei n = 8 sind das 40.320 Mischvorgänge).

+

Darstellung: Bogo Sort erzeugt ein hektisches Blitz-Muster: Das gesamte Array blinkt rot auf (Shuffle), dann wandern kurze orange Bögen von links nach rechts durch das Array (Sortiertheitscheck). Scheitert die Prüfung, folgt sofort der nächste rote Shuffle. Die kleinen Wertemarken unter den Balken zeigen bei jedem Shuffle-Versuch eine neue zufällige Anordnung. Der Fortschrittsbalken bewegt sich kaum — tausende Schritte bei nur 8 Elementen zeigen eindrücklich, wie nutzlos rein zufälliges Probieren ist. Die Array-Größe ist automatisch auf 8 begrenzt.

+

Wann einsetzen: Niemals in der Praxis. Bogo Sort dient als Lehr- und Abschreckungsbeispiel: Er zeigt eindrücklich, warum zufälliges Probieren exponentiell schlecht skaliert. Bei nur 8 Elementen braucht er im Schnitt ~40.000 Versuche, bei 10 Elementen schon ~3,6 Millionen. Der Name ist ein Wortspiel auf „bogus" (falsch/wertlos). In der theoretischen Informatik dient er als Referenz für die schlechteste denkbare Komplexitätsklasse. Die Array-Größe wird hier automatisch auf 8 begrenzt, um den Browser nicht einzufrieren.

+
+ +
+

Fisher-Yates Shuffle

+
+ Stabil + In-place + O(n) Zeit · O(1) Speicher +
+

Funktionsweise: Der Fisher-Yates-Algorithmus (auch Knuth-Shuffle) mischt ein Array uniform zufällig. Er läuft rückwärts: Für jede Position i wird ein zufälliger Index j zwischen 0 und i gewählt und die beiden Elemente getauscht. Jede der n! Permutationen wird mit gleicher Wahrscheinlichkeit erzeugt.

+

Darstellung: Rote Bögen zeigen jeden Tausch — keine Vergleiche, nur Tausche. Die Anzahl der Tausche ist immer n-1 (bei n Elementen). Das macht die Effizienz des Mischens im Vergleich zum Sortieren direkt sichtbar.

+

Wann einsetzen: Zum Erzeugen von Testdaten, zum „Nochmal-Mischen" eines sortierten Arrays, oder als Gegenbeweis: Ein einziger Shuffle macht jede Sortierung rückgängig. Mischen ist O(n), Sortieren ist O(n log n) — also ist Mischen immer schneller als Sortieren.

+
+ +
+
+ +
+
+ + +
+ + + Bedienung + + +
+ +

Was ist das? Dieses Programm visualisiert die Funktionsweise von 20 Sortieralgorithmen — von Bubble Sort bis Fisher-Yates Shuffle. Es zeigt Schritt für Schritt, wie ein Algorithmus ein Array sortiert, macht die Datenstrukturen und Speichernutzung sichtbar und vermittelt ein intuitives Verständnis dafür, warum der eine Algorithmus schneller ist als der andere.

+ + +
+

Quick-Start

+
    +
  1. 1. Wähle einen Algorithmus aus dem Dropdown-Menü.
  2. +
  3. 2. Stelle die Array-Größe und Geschwindigkeit ein.
  4. +
  5. 3. Drücke Space zum Starten — oder nutze die Schritt-für-Schritt-Navigation.
  6. +
+
+ + +
+

Steuerung

+
+
+ + Play / Pause — Animation starten oder anhalten +
+
+ + Ein Schritt vor — nächste Operation +
+
+ + Ein Schritt zurück — vorherige Operation +
+
+ + Reset — Array in Ausgangszustand zurücksetzen +
+
+ 🔀 + Mischen — Fisher-Yates Shuffle auf aktuelles Array +
+
+ 🌙/☀ + Theme — zwischen hellem und dunklem Modus wechseln +
+
+
+ + +
+

Tastaturkürzel

+
+
Space Play/Pause
+
K Play/Pause
+
Schritt zurück
+
J Schritt zurück
+
Schritt vor
+
L Schritt vor
+
R Reset
+
T Theme
+
S Shuffle
+
+
+ + +
+

Datensätze

+
+
Zufällig — zufällig verteilte Werte, der Standard-Testfall.
+
Sortiert — bereits in aufsteigender Reihenfolge. Manche Algorithmen (z.B. Quick Sort mit erstem Element als Pivot) werden dadurch extrem langsam.
+
Umgekehrt — absteigend sortiert. Das Gegenstück zu „Sortiert" und ein公平er Test für die meisten Algorithmen.
+
Fast sortiert — nur wenige Elemente sind an der falschen Stelle. Adaptiven Algorithmen (Insertion Sort, Timsort) spielen hier ihre Stärke aus.
+
Duplikate — viele gleiche Werte. Das ist der Härtetest für Algorithmen wie Quick Sort (degeneriert zu O(n²)), während 3-Way Quick Sort hier brilliert.
+
+
+ + +
+

Warum sind Sortieralgorithmen wichtig?

+

Sortieren ist eines der am intensivsten erforschten Probleme der Informatik — nicht aus akademischer Überheblichkeit, sondern weil es in der Praxis überall vorkommt: Datenbankabfragen müssen Ergebnisse sortieren, Betriebssysteme verwalten Prioritätswarteschlangen, Compiler nutzen Sortieralgorithmen für die Optimierung. Die Wahl des richtigen Algorithmus kann den Unterschied ausmachen zwischen einer Antwort in Millisekunden und in Minuten.

+

Jeder Algorithmus repräsentiert einen grundlegenden Kompromiss: Manche sind einfach zu verstehen (Bubble Sort), andere extrem schnell im Durchschnitt (Quick Sort), wieder andere garantieren auch im schlimmsten Fall gute Leistung (Heap Sort). Wer diese Kompromisse versteht, kann für jede Situation die richtige Wahl treffen — sei es beim Sortieren von 100 Datensätzen oder 100 Millionen.

+

Dieses Programm hilft dabei, ein intuitives Gespür für diese Kompromisse zu entwickeln. Beobachten Sie, wie Bubble Sort bei sortierten Daten plötzlich in O(n) abschließt, während er bei umgekehrt sortierten Daten genauso langsam ist wie immer. Oder wie Timsort die Ordnung in fast-sortierten Daten sofort erkennt und ausnutzt. Visuelles Lernen macht sichtbar, was Paper und Pseudocode nur schwer vermitteln.

+
+ +
+
+ +
+ + + +
+ © 2026 Dieter Schlüter <dieter(dot)schlueter(at)linux(dot)de> +
+ + + diff --git a/test_algorithms.js b/test_algorithms.js new file mode 100644 index 0000000..0396fb6 --- /dev/null +++ b/test_algorithms.js @@ -0,0 +1,448 @@ +/** + * Test-Skript für Sortieralgorithmen + * Extrahiert buildSteps aus sorting_visualization.html und testet alle Algorithmen + * + * Usage: + * node test_algorithms.js # Kurzbericht + * node test_algorithms.js --verbose # Detaillierte Ausgabe + */ + +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import vm from 'node:vm'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const verbose = process.argv.includes('--verbose'); + +// ── HTML parsen und JS extrahieren ── +const html = fs.readFileSync(path.join(__dirname, 'sorting_visualization.html'), 'utf-8'); + +// Finde den letzten ', closeIdx); + if (endIdx === -1) break; + const content = html.substring(closeIdx + 1, endIdx); + scriptBlocks.push({ tag, content, start: closeIdx + 1 }); + idx = endIdx + 9; +} + +// Nimm den Block der 'function buildSteps' enthält +const codeBlock = scriptBlocks.find(b => b.content.includes('function buildSteps')); +if (!codeBlock) { + console.error('Fehler: Kein