Algorithmen einfach erklärt | Grundlagen & Beispiele
Programmierung Grundlagen

Algorithmen verstehen

Probleme in klare, ausführbare Schritte zerlegen – mit Pseudocode, Such- und Sortierverfahren, verständlicher Laufzeitanalyse und interaktiven Übungen.

Für Einsteiger Pseudocode Suchen & Sortieren Interaktive Simulatoren

🛠️ Empfohlene Tools für Entwickler

Diese Tools nutze ich selbst – sie helfen Ihnen, Ihre Projekte professionell umzusetzen und zu vermarkten.

⚡ ExeOutput for PHP

PHP-Anwendungen in eigenständige Windows-EXE-Dateien kompilieren – ideal für die Auslieferung Ihrer Algorithmen.

Jetzt ansehen →

📄 HTML Executable

HTML-Dateien und Websites als eigenständige Windows-EXE-Dateien kompilieren.

Jetzt ansehen →

🔒 XLS Padlock

Excel-Arbeitsmappen als EXE kompilieren und schützen – perfekt für datenbank-gestützte Excel-Lösungen mit Algorithmen.

Jetzt ansehen →

🐍 VBA Padlock

VBA-Code kompilieren und Office-Lösungen verkaufen – ohne Source-Code-Weitergabe.

Jetzt ansehen →

📦 Paquet Builder

Professionelle Windows-Installationsprogramme für Ihre Anwendungen erstellen.

Jetzt ansehen →

* Affiliate-Links: Bei einem Kauf über diese Links erhalten wir eine kleine Provision – für Sie entstehen keine zusätzlichen Kosten.

1. Was ist ein Algorithmus?

Ein Algorithmus ist eine eindeutige Folge ausführbarer Schritte, die Eingaben verarbeitet und zu einem gewünschten Ergebnis führt. Er beschreibt die Lösung unabhängig davon, in welcher Programmiersprache sie später umgesetzt wird.

Eingabe

Die Informationen, mit denen der Algorithmus startet, zum Beispiel eine Zahlenliste und ein gesuchter Wert.

Verarbeitung

Die festgelegten Schritte, Bedingungen und Wiederholungen, die auf den Eingaben ausgeführt werden.

Ausgabe

Das Ergebnis, zum Beispiel der gefundene Listenindex, eine sortierte Liste oder eine berechnete Summe.

Vergleich mit einem Kochrezept: Zutaten sind die Eingaben, Arbeitsschritte bilden die Verarbeitung und das fertige Gericht ist die Ausgabe. Fehlen Mengen, Reihenfolge oder Abbruchbedingungen, wird das Ergebnis unzuverlässig.

Algorithmen begegnen uns überall

  • Eine Navigation berechnet eine geeignete Route.
  • Ein Onlineshop sortiert Produkte nach Preis oder Relevanz.
  • Eine Tabellenkalkulation verarbeitet Daten nach Formeln und Regeln.
  • Eine Suchfunktion prüft Datensätze auf einen passenden Wert.
  • Kompressions- und Verschlüsselungsverfahren transformieren Informationen.

2. Eigenschaften eines guten Algorithmus

Eine bloße Liste von Anweisungen reicht nicht. Ein brauchbarer Algorithmus sollte mehrere Qualitätsmerkmale erfüllen.

1

Eindeutig

Jeder Schritt ist so genau beschrieben, dass er nicht unterschiedlich ausgelegt werden muss.

2

Ausführbar

Alle Einzelschritte können mit den verfügbaren Mitteln tatsächlich durchgeführt werden.

3

Endlich

Für zulässige Eingaben endet die Ausführung nach einer begrenzten Zahl von Schritten.

4

Korrekt

Für den vorgesehenen Eingabebereich entsteht das fachlich richtige Ergebnis.

5

Allgemein

Die Lösung funktioniert nicht nur für ein einzelnes Beispiel, sondern für eine definierte Problemklasse.

6

Nachvollziehbar

Aufbau, Annahmen und Entscheidungen sind verständlich dokumentiert und testbar.

Korrekt vor schnell: Zuerst muss die Lösung zuverlässig funktionieren. Danach wird gemessen, ob Laufzeit oder Speicherbedarf tatsächlich verbessert werden müssen.

3. Eingabe – Verarbeitung – Ausgabe

Das EVA-Prinzip hilft, ein Problem in drei übersichtliche Bereiche zu zerlegen.

EingabePreis: 100 €
Stammkunde: ja
Verarbeitung10 % Rabatt berechnen
AusgabeEndpreis: 90 €
PrüfungErwartung erfüllt?
PseudocodePreis mit Rabatt
EINGABE preis, ist_stammkunde

WENN ist_stammkunde = wahr DANN
    endpreis ← preis × 0,90
SONST
    endpreis ← preis
ENDE WENN

AUSGABE endpreis

Vor dem Programmieren klären

  • Welche Eingaben sind erlaubt?
  • Welche Ausgabe wird genau erwartet?
  • Welche Sonderfälle können auftreten?
  • Wann soll der Ablauf enden?
  • Woran wird die Korrektheit geprüft?

4. Einen Algorithmus darstellen

Algorithmen können auf verschiedene Weise beschrieben werden. Die passende Darstellung hängt von Zielgruppe, Komplexität und Entwicklungsphase ab.

Alltagssprache

Einfach zugänglich, aber bei komplexen Abläufen schnell mehrdeutig.

Pseudocode

Programmierähnlich und dennoch unabhängig von einer konkreten Sprache.

Ablaufdiagramm

Stellt Reihenfolge, Entscheidungen und Schleifen visuell dar.

Programmcode

Ist exakt ausführbar, enthält jedoch sprachspezifische Syntax und technische Details.

Beispiel: größere von zwei Zahlen

PseudocodeEntscheidung
EINGABE a, b

WENN a > b DANN
    AUSGABE a
SONST
    AUSGABE b
ENDE WENN
Gute Vorgehensweise: Beschreibe zuerst Eingabe, gewünschte Ausgabe und Sonderfälle. Formuliere anschließend Pseudocode und übertrage ihn erst danach in Python, JavaScript oder eine andere Sprache.

5. Sequenz, Auswahl und Wiederholung

Sehr viele Algorithmen lassen sich aus drei grundlegenden Kontrollstrukturen zusammensetzen.

Sequenz

Anweisungen werden in festgelegter Reihenfolge nacheinander ausgeführt.

PseudocodeSequenz
wasser_einfüllen
wasser_erhitzen
kaffee_aufgießen

Auswahl

Eine Bedingung entscheidet, welcher Weg ausgeführt wird.

PseudocodeBedingung
WENN temperatur > 90 DANN
    heizung_ausschalten
SONST
    weiter_erhitzen

Wiederholung

Eine Anweisung wird für Werte oder solange eine Bedingung gilt wiederholt.

PseudocodeSchleife
FÜR jede zahl IN zahlen
    summe ← summe + zahl
ENDE FÜR
Schleifen benötigen Fortschritt: Bei einer bedingten Wiederholung muss sich mindestens ein relevanter Zustand verändern. Andernfalls kann eine Endlosschleife entstehen.

6. Wichtige Algorithmen-Typen

Suchalgorithmen

Finden Werte oder Positionen, zum Beispiel lineare und binäre Suche.

Sortieralgorithmen

Ordnen Daten, zum Beispiel Bubble Sort, Merge Sort oder Quicksort.

Graphalgorithmen

Untersuchen Netzwerke, Wege und Verbindungen, etwa in Navigation oder sozialen Beziehungen.

Kryptografische Algorithmen

Schützen Integrität und Vertraulichkeit oder erzeugen überprüfbare Signaturen.

Kompressionsalgorithmen

Reduzieren Datenmengen verlustfrei oder verlustbehaftet, abhängig vom Einsatzzweck.

Optimierungsalgorithmen

Suchen unter vielen Möglichkeiten nach einer möglichst guten Lösung.

Datenstruktur und Algorithmus gehören zusammen: Ob Daten als Liste, Menge, Baum oder Graph organisiert sind, beeinflusst stark, welche Lösung sinnvoll und effizient ist.

7. Lineare Suche

Die lineare Suche prüft Elemente der Reihe nach, bis der Zielwert gefunden wurde oder das Ende erreicht ist. Sie funktioniert auch mit unsortierten Daten.

Zeit: O(n) · Zusatzspeicher: O(1)

Grundidee

Bei einer Liste mit n Elementen sind im ungünstigsten Fall n Vergleiche nötig.

PseudocodeLineare Suche
FUNKTION lineare_suche(liste, ziel)
    FÜR index VON 0 BIS länge(liste) - 1
        WENN liste[index] = ziel DANN
            RÜCKGABE index
        ENDE WENN
    ENDE FÜR

    RÜCKGABE -1
ENDE FUNKTION

Wann ist sie sinnvoll?

  • Die Daten sind klein oder unsortiert.
  • Es wird nur selten gesucht.
  • Die Reihenfolge darf nicht verändert werden.
  • Eine einfache, gut verständliche Lösung ist wichtiger als maximale Geschwindigkeit.

8. Binäre Suche

Die binäre Suche vergleicht den Zielwert mit dem mittleren Element. Danach wird nur in der passenden Hälfte weitergesucht. Dafür müssen die Daten nach derselben Ordnung sortiert sein.

Zeit: O(log n) · Zusatzspeicher iterativ: O(1)

Grundidee

Der verbleibende Suchbereich wird mit jedem Vergleich ungefähr halbiert. Bei großen sortierten Datenmengen ist das deutlich effizienter als eine vollständige lineare Suche.

PseudocodeBinäre Suche
FUNKTION binaere_suche(liste, ziel)
    links ← 0
    rechts ← länge(liste) - 1

    SOLANGE links <= rechts
        mitte ← ganzzahl((links + rechts) / 2)

        WENN liste[mitte] = ziel DANN
            RÜCKGABE mitte
        SONST WENN liste[mitte] < ziel DANN
            links ← mitte + 1
        SONST
            rechts ← mitte - 1
        ENDE WENN
    ENDE SOLANGE

    RÜCKGABE -1
ENDE FUNKTION
Voraussetzung: Eine binäre Suche auf unsortierten Daten liefert keine verlässlichen Ergebnisse. Das vorherige Sortieren lohnt sich vor allem, wenn anschließend häufig gesucht wird oder die Daten bereits sortiert vorliegen.

9. Sortieren mit Bubble Sort

Bubble Sort vergleicht benachbarte Elemente und vertauscht sie, wenn sie in der falschen Reihenfolge stehen. Nach jedem vollständigen Durchlauf befindet sich mindestens ein großes Element an seiner endgültigen Position.

Durchschnitt und ungünstigster Fall: O(n²)

Stärke und Grenze

Bubble Sort ist leicht zu erklären und eignet sich gut zum Lernen. Für größere Datenmengen werden meist effizientere Sortierverfahren oder die eingebaute Sortierfunktion der Sprache verwendet.

PseudocodeOptimierter Bubble Sort
FUNKTION bubble_sort(zahlen)
    n ← länge(zahlen)

    FÜR i VON 0 BIS n - 2
        wurde_vertauscht ← falsch

        FÜR j VON 0 BIS n - i - 2
            WENN zahlen[j] > zahlen[j + 1] DANN
                VERTAUSCHE zahlen[j] MIT zahlen[j + 1]
                wurde_vertauscht ← wahr
            ENDE WENN
        ENDE FÜR

        WENN wurde_vertauscht = falsch DANN
            ABBRUCH
        ENDE WENN
    ENDE FÜR

    RÜCKGABE zahlen
ENDE FUNKTION

🎯 Live-Demo: Bubble Sort Visualisierung

Hier sehen Sie eine vereinfachte Bubble-Sort-Animation:

9
4
7
2
8
1
Klick auf "Bubble Sort starten"

10. Quicksort – Teile und Herrsche

Quicksort ist ein effizienter, vergleichsbasierter Sortieralgorithmus. Er wählt ein Pivot-Element und teilt die Liste so auf, dass alle kleineren Elemente links und alle größeren rechts stehen. Dann werden beide Teile rekursiv sortiert.

Durchschnitt: O(n log n) · Ungünstigster Fall: O(n²) Zusatzspeicher: O(log n) (rekursiv)

Grundidee

Quicksort ist in der Praxis oft schneller als Merge Sort, weil er in-place sortiert und gute Cache-Eigenschaften hat. Der ungünstigste Fall (z.B. bereits sortierte Liste mit ungünstigem Pivot) ist jedoch möglich.

PseudocodeQuicksort
FUNKTION quicksort(zahlen, links, rechts)
    WENN links < rechts DANN
        p ← partition(zahlen, links, rechts)
        quicksort(zahlen, links, p - 1)
        quicksort(zahlen, p + 1, rechts)
    ENDE WENN
ENDE FUNKTION

FUNKTION partition(zahlen, links, rechts)
    pivot ← zahlen[rechts]
    i ← links - 1

    FÜR j VON links BIS rechts - 1
        WENN zahlen[j] <= pivot DANN
            i ← i + 1
            VERTAUSCHE zahlen[i] MIT zahlen[j]
        ENDE WENN
    ENDE FÜR

    VERTAUSCHE zahlen[i + 1] MIT zahlen[rechts]
    RÜCKGABE i + 1
ENDE FUNKTION
Pivot-Strategien: Die Wahl des Pivot-Elements beeinflusst die Performance. Gute Strategien sind das mittlere Element, ein zufälliges Element oder "Median of Three" (erster, mittlerer, letzter Wert).

11. Merge Sort – Stabile Sortierung

Merge Sort teilt die Liste in zwei Hälften, sortiert jede Hälfte rekursiv und führt sie dann sortiert zusammen. Er ist stabil und hat eine garantierte Laufzeit von O(n log n).

Zeit: O(n log n) · Zusatzspeicher: O(n)

Grundidee

Merge Sort eignet sich besonders für große Datenmengen und wenn eine stabile Sortierung benötigt wird. Der zusätzliche Speicherbedarf ist jedoch höher als bei Quicksort.

PseudocodeMerge Sort
FUNKTION merge_sort(zahlen)
    WENN länge(zahlen) <= 1 DANN
        RÜCKGABE zahlen
    ENDE WENN

    mitte ← länge(zahlen) / 2
    links ← zahlen[0:mitte]
    rechts ← zahlen[mitte:länge(zahlen)]

    links_sortiert ← merge_sort(links)
    rechts_sortiert ← merge_sort(rechts)

    RÜCKGABE merge(links_sortiert, rechts_sortiert)
ENDE FUNKTION

FUNKTION merge(links, rechts)
    ergebnis ← []
    SOLANGE links UND rechts
        WENN links[0] <= rechts[0] DANN
            ergebnis.hinzufügen(links.entferne_erstes())
        SONST
            ergebnis.hinzufügen(rechts.entferne_erstes())
        ENDE WENN
    ENDE SOLANGE

    RÜCKGABE ergebnis + links + rechts
ENDE FUNKTION
Stabilität: Merge Sort behält die relative Reihenfolge gleicher Elemente bei. Das ist wichtig, wenn nach mehreren Kriterien sortiert wird.

12. Heapsort – Sortieren mit Heap

Heapsort nutzt eine Heap-Datenstruktur (Binärbaum) zum Sortieren. Er baut zunächst einen Max-Heap auf und entfernt dann sukzessive das größte Element.

Zeit: O(n log n) · Zusatzspeicher: O(1)

Grundidee

Heapsort ist in-place und hat eine garantierte Laufzeit von O(n log n). Er ist jedoch meist langsamer als Quicksort in der Praxis.

PseudocodeHeapsort
FUNKTION heap_sort(zahlen)
    n ← länge(zahlen)

    FÜR i VON n/2 - 1 BIS 0
            heapify(zahlen, n, i)
    ENDE FÜR

    FÜR i VON n - 1 BIS 1
        VERTAUSCHE zahlen[0] MIT zahlen[i]
        heapify(zahlen, i, 0)
    ENDE FÜR

    RÜCKGABE zahlen
ENDE FUNKTION

FUNKTION heapify(zahlen, n, i)
    grösste ← i
    links ← 2 * i + 1
    rechts ← 2 * i + 2

    WENN links < n UND zahlen[links] > zahlen[grösste] DANN
        grösste ← links
    ENDE WENN

    WENN rechts < n UND zahlen[rechts] > zahlen[grösste] DANN
        grösste ← rechts
    ENDE WENN

    WENN grösste ≠ i DANN
        VERTAUSCHE zahlen[i] MIT zahlen[grösste]
        heapify(zahlen, n, grösste)
    ENDE WENN
ENDE FUNKTION
Wann Heapsort? Heapsort eignet sich besonders, wenn eine garantierte Laufzeit von O(n log n) benötigt wird und kein zusätzlicher Speicher verwendet werden darf (z.B. in eingebetteten Systemen).

13. Rekursion verstehen

Eine rekursive Funktion löst ein Problem, indem sie eine kleinere Version desselben Problems aufruft. Jede Rekursion benötigt einen Basisfall, der weitere Aufrufe beendet.

PseudocodeFakultät
FUNKTION fakultaet(n)
    WENN n = 0 DANN
        RÜCKGABE 1          # Basisfall
    ENDE WENN

    RÜCKGABE n × fakultaet(n - 1)
ENDE FUNKTION

Für fakultaet(4) entstehen die Aufrufe 4 × 3 × 2 × 1 × fakultaet(0). Der Basisfall liefert 1 und beendet die Kette.

🎯 Live-Demo: Fibonacci – Rekursiv vs. Iterativ

Vergleiche die Laufzeit beider Ansätze:

Klick auf einen Button...
Nicht automatisch besser: Rekursion kann Baum- und Graphprobleme elegant beschreiben, benötigt jedoch Aufrufspeicher und kann bei großer Tiefe Grenzen erreichen. Eine Schleife ist bei einfachen Wiederholungen oft direkter.

14. Dynamische Programmierung

Dynamische Programmierung löst komplexe Probleme, indem sie sie in überlappende Teilprobleme zerlegt und die Ergebnisse zwischenspeichert (Memoization).

Typischerweise O(n²) bis O(n³)

Grundidee

Die dynamische Programmierung eignet sich besonders für Optimierungsprobleme, bei denen die Lösung aus optimalen Teillösungen besteht.

PythonFibonacci mit Memoization
def fib_memo(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo)
    return memo[n]
Klassiker der dynamischen Programmierung: Rucksackproblem (0/1), Editierdistanz, längste gemeinsame Teilfolge, Münzproblem, Matrixmultiplikationsreihenfolge.

15. Greedy-Algorithmen

Greedy-Algorithmen treffen in jedem Schritt die lokal beste Entscheidung, in der Hoffnung, dass dies zur global optimalen Lösung führt.

Typischerweise O(n log n) bis O(n²)

Grundidee

Greedy-Algorithmen sind einfach und schnell, funktionieren aber nicht immer optimal. Sie eignen sich für Probleme, bei denen eine lokale Entscheidung die globale Lösung nicht gefährdet.

PseudocodeMünzwechsel (Greedy)
FUNKTION muenzwechsel(betrag, münzen)
    ergebnis ← []
    münzen ← sortiere_absteigend(münzen)

    FÜR jede münze IN münzen
        während betrag >= münze
            ergebnis.hinzufügen(münze)
            betrag ← betrag - münze
        ENDE WÄHREND
    ENDE FÜR

    RÜCKGABE ergebnis
ENDE FUNKTION
Nicht immer optimal: Greedy-Algorithmen liefern nicht immer die optimale Lösung. Beispiel: Münzen [10, 6, 1], Betrag 12 → Greedy: 10+1+1 (3 Münzen), optimal: 6+6 (2 Münzen).

16. Backtracking

Backtracking ist eine systematische Suchmethode, die alle möglichen Lösungen durchprobiert und bei Sackgassen zurückspringt.

Typischerweise exponentiell O(2ⁿ)

Grundidee

Backtracking eignet sich für Probleme, bei denen alle Kombinationen geprüft werden müssen – wie das 8-Damen-Problem, Sudoku oder das Lösen von Rätseln.

PseudocodeN-Damen Backtracking
FUNKTION n_damen(n, reihe, damen)
    WENN reihe = n DANN
        RÜCKGABE damen           # Lösung gefunden
    ENDE WENN

    FÜR spalte VON 0 BIS n - 1
        WENN konflikt_frei(reihe, spalte, damen) DANN
            damen[reihe] ← spalte
            ergebnis ← n_damen(n, reihe + 1, damen)
            WENN ergebnis ≠ NULL DANN
                RÜCKGABE ergebnis
            ENDE WENN
        ENDE WENN
    ENDE FÜR

    RÜCKGABE NULL               # Keine Lösung gefunden
ENDE FUNKTION

17. Divide-and-Conquer

Divide-and-Conquer (Teile und Herrsche) zerlegt ein Problem in kleinere Teilprobleme, löst sie rekursiv und setzt die Lösungen zusammen.

Typischerweise O(n log n)

Grundidee

Diese Strategie wird bei Merge Sort, Quicksort, binärer Suche und vielen anderen effizienten Algorithmen verwendet.

AlgorithmusDivideConquerCombine
Merge SortListe halbierenSortierenZusammenführen
QuicksortPartitionierenSortieren– (in-place)
Binäre SucheMitte findenIn Hälfte suchen
KaratsubaMultiplikation aufteilenTeilprodukteKombinieren

18. Big O – wie wächst der Aufwand?

Die Big-O-Notation beschreibt vereinfacht, wie stark Laufzeit oder Speicherbedarf mit wachsender Eingabegröße n zunehmen. Sie nennt keine exakten Sekunden.

KlasseBezeichnungVereinfachtes BeispielWachstum
O(1)KonstantElement über bekannten Listenindex lesenUnabhängig von n
O(log n)LogarithmischBinäre Suche in sortierter ListeSehr langsam steigend
O(n)LinearListe einmal vollständig durchlaufenProportional zu n
O(n log n)Linear-logarithmischEffiziente vergleichsbasierte SortierungMeist gut skalierend
O(n²)QuadratischViele doppelt verschachtelte VergleicheBei großen n schnell teuer
O(2ⁿ)ExponentiellNaive Untersuchung vieler TeilmengenSehr stark wachsend

Warum Konstanten trotzdem zählen

Zwei Verfahren mit derselben Big-O-Klasse können in der Praxis unterschiedlich schnell sein. Programmiersprache, Datenstruktur, Speicherzugriffe, Eingabeverteilung und konstante Faktoren bleiben relevant. Big O ist ein Werkzeug für das Wachstum, nicht die vollständige Leistungsbewertung.

Merksatz: Bei kleinen Daten gewinnt häufig die einfachere Lösung. Bei stark wachsenden Daten wird die Wachstumsklasse zunehmend wichtig. Messen solltest du immer mit realistischen Eingaben.

19. Algorithmen in Python und JavaScript

Lineare Suche in Python

Pythonlineare_suche.py
def lineare_suche(werte, ziel):
    for index, wert in enumerate(werte):
        if wert == ziel:
            return index
    return -1


zahlen = [8, 3, 14, 7, 21]
print(lineare_suche(zahlen, 14))  # 2

Binäre Suche in JavaScript

JavaScriptbinaere-suche.js
function binaereSuche(werte, ziel) {
    let links = 0;
    let rechts = werte.length - 1;

    while (links <= rechts) {
        const mitte = Math.floor((links + rechts) / 2);

        if (werte[mitte] === ziel) {
            return mitte;
        }

        if (werte[mitte] < ziel) {
            links = mitte + 1;
        } else {
            rechts = mitte - 1;
        }
    }

    return -1;
}

const zahlen = [3, 7, 12, 18, 25, 31, 42];
console.log(binaereSuche(zahlen, 25)); // 4

Bubble Sort in Python

Pythonbubble_sort.py
def bubble_sort(werte):
    ergebnis = werte.copy()
    n = len(ergebnis)

    for i in range(n - 1):
        wurde_vertauscht = False

        for j in range(n - 1 - i):
            if ergebnis[j] > ergebnis[j + 1]:
                ergebnis[j], ergebnis[j + 1] = ergebnis[j + 1], ergebnis[j]
                wurde_vertauscht = True

        if not wurde_vertauscht:
            break

    return ergebnis


print(bubble_sort([9, 4, 7, 2, 8, 1]))
Keine unbeabsichtigte Änderung: Das Python-Beispiel sortiert eine Kopie der übergebenen Liste. Dadurch bleibt die ursprüngliche Eingabe unverändert.

20. Interaktives Suchlabor

Vergleiche lineare und binäre Suche Schritt für Schritt. Für die binäre Suche muss die Zahlenliste aufsteigend sortiert sein.

Suche konfigurieren

Maximal 20 Zahlen, getrennt durch Komma oder Leerzeichen.
Wähle ein Verfahren und bereite die Suche vor.
Vergleiche: 0 Suchbereich: –

21. Interaktives Bubble-Sort-Labor

Beobachte, wie Bubble Sort benachbarte Zahlen vergleicht und bei Bedarf vertauscht. Grün markierte Bereiche sind bereits endgültig einsortiert.

Sortierung konfigurieren

Maximal 12 Zahlen, getrennt durch Komma oder Leerzeichen.
Bereite eine Zahlenliste für die Sortierung vor.
Vergleiche: 0 Vertauschungen: 0 Durchlauf: –

22. Fibonacci-Vergleich: Rekursiv vs. Iterativ

Dieses Labor zeigt den dramatischen Performance-Unterschied zwischen rekursiver und iterativer Implementierung der Fibonacci-Folge.

Fibonacci berechnen

Gib eine Zahl ein und klicke auf "Berechnen".
Ergebnis: – Zeit: – Aufrufe: –
Achtung: Die rekursive Berechnung ohne Memoization wird für n > 35 sehr langsam. Das Labor zeigt die exponentielle Komplexität O(2ⁿ) anschaulich.

23. Den passenden Algorithmus auswählen

Es gibt selten einen Algorithmus, der für jede Situation am besten ist. Eine gute Entscheidung berücksichtigt Anforderungen und Daten gemeinsam.

  1. 1
    Problem präzisierenWelche Eingaben, Ausgaben und fachlichen Regeln sind verbindlich?
  2. 2
    Daten verstehenWie groß sind sie, sind sie sortiert und wie häufig ändern sie sich?
  3. 3
    Grenzfälle sammelnLeere Eingabe, doppelte Werte, ungültige Daten und sehr große Mengen berücksichtigen.
  4. 4
    Einfache korrekte Lösung bauenVerständlichkeit und Testbarkeit bilden die erste stabile Grundlage.
  5. 5
    Messen und vergleichenMit realistischen Daten prüfen, ob Laufzeit oder Speicher tatsächlich problematisch sind.
  6. 6
    Gezielt optimierenNur den nachgewiesenen Engpass verbessern und Korrektheit erneut testen.
SituationErste sinnvolle WahlBegründung
Kleine unsortierte Liste, einmalige SucheLineare SucheEinfach und ohne vorheriges Sortieren.
Große bereits sortierte ListeBinäre SucheSuchbereich wird wiederholt halbiert.
Viele Suchvorgänge nach exakten SchlüsselnPassende indexierte DatenstrukturVorbereitung kann sich durch häufige Abfragen lohnen.
Sehr kleine oder fast sortierte ListeEinfaches geeignetes SortierverfahrenGeringer Verwaltungsaufwand kann wichtiger sein.
Große Daten, garantierte LaufzeitMerge Sort oder HeapsortO(n log n) garantiert, keine schlechten Fälle.
Große Daten, gute DurchschnittsleistungQuicksortIn der Praxis meist am schnellsten.

24. Checkliste für einen zuverlässigen Algorithmus

Hake die erledigten Punkte ab. Die Auswahl bleibt nur während dieses Seitenaufrufs erhalten.

0 von 10 Punkten erledigt

25. Häufige Fehler und Lösungen

Falsche Bereichsgrenzen

Problem: Eine Schleife läuft ein Element zu weit oder überspringt das letzte Element.

Lösung: Kleinste Listen mit null, einem und zwei Elementen Schritt für Schritt testen.

Binäre Suche auf unsortierten Daten

Problem: Das Halbieren basiert auf einer Ordnung, die nicht vorhanden ist.

Lösung: Sortierung als Vorbedingung dokumentieren und vor der Suche sicherstellen.

Fehlender Abbruch bei Rekursion

Problem: Rekursion erreicht keinen sicheren Endzustand (Stack Overflow).

Lösung: Basisfall und Fortschritt mit Grenzfällen nachvollziehen.

Zu frühe Optimierung

Problem: Komplexer Code entsteht, obwohl noch kein gemessener Engpass existiert.

Lösung: Erst korrekt und verständlich lösen, danach messen und gezielt verbessern.

Greedy funktioniert nicht optimal

Problem: Die lokale Entscheidung führt nicht zur global optimalen Lösung.

Lösung: Prüfen, ob das Problem die Greedy-Eigenschaft erfüllt. Sonst dynamische Programmierung verwenden.

26. Übungen zum Mitmachen

Löse die Aufgaben zuerst in Alltagssprache oder Pseudocode und übertrage sie anschließend in eine Programmiersprache.

Übung 1 · Einstieg

Größten Wert finden

Entwickle einen Algorithmus, der den größten Wert einer nicht leeren Zahlenliste zurückgibt.

Übung 2 · Einstieg

Gerade Zahlen zählen

Zähle, wie viele gerade Zahlen in einer Liste enthalten sind.

Übung 3 · Mittel

Lineare Suche erweitern

Gib nicht nur den ersten, sondern alle Indizes eines Zielwertes zurück.

Übung 4 · Mittel

Bubble Sort absteigend

Ändere den Vergleich so, dass die größte Zahl am Anfang steht.

Übung 5 · Fortgeschritten

Quicksort implementieren

Implementiere Quicksort in einer Sprache deiner Wahl und teste ihn mit verschiedenen Eingaben.

Übung 6 · Fortgeschritten

Fibonacci mit Memoization

Implementiere Fibonacci mit Memoization und vergleiche die Laufzeit mit der naiven rekursiven Version.

Lösungshinweise

Hinweis zu Übung 1 anzeigen

Starte mit dem ersten Listenelement als bisherigem Maximum. Vergleiche danach jedes weitere Element und ersetze das Maximum, wenn ein größerer Wert gefunden wird.

Hinweis zu Übung 2 anzeigen

Initialisiere einen Zähler mit null. Erhöhe ihn für jeden Wert, dessen Rest bei Division durch 2 gleich null ist.

Hinweis zu Übung 3 anzeigen

Lege eine leere Ergebnisliste an. Füge bei jedem Treffer den aktuellen Index hinzu und gib die Liste nach dem vollständigen Durchlauf zurück.

Hinweis zu Übung 4 anzeigen

Vertausche benachbarte Werte, wenn der linke Wert kleiner als der rechte ist. Teste danach, welche Position pro Durchlauf endgültig sortiert wird.

Hinweis zu Übung 5 anzeigen

Wähle einen Pivot (z.B. mittleres Element), partitioniere die Liste und rufe Quicksort rekursiv auf beiden Hälften auf.

Hinweis zu Übung 6 anzeigen

Verwende ein Dictionary oder eine Liste als Cache. Speichere jeden berechneten Fibonacci-Wert und rufe ihn bei Bedarf ab.

27. Passende nächste Themen

Diese Grundlagen-Seiten vertiefen die praktische Umsetzung und die Wahl geeigneter Datenmodelle.

28. Häufige Fragen zu Algorithmen

Ist jeder Programmcode ein Algorithmus?

Programmcode setzt häufig einen oder mehrere Algorithmen um, enthält aber zusätzlich technische Details, Ein- und Ausgabe, Fehlerbehandlung und Bibliotheksaufrufe. Ein Algorithmus beschreibt vor allem das grundlegende Lösungsverfahren.

Muss ein Algorithmus in einer Programmiersprache geschrieben sein?

Nein. Er kann in Alltagssprache, Pseudocode oder einem Ablaufdiagramm beschrieben werden. Entscheidend sind eindeutige, ausführbare und endliche Schritte.

Was ist der Unterschied zwischen Algorithmus und Datenstruktur?

Eine Datenstruktur organisiert Informationen. Ein Algorithmus verarbeitet diese Informationen. Beide beeinflussen sich gegenseitig: Eine passende Datenstruktur kann bestimmte Operationen erheblich vereinfachen oder beschleunigen.

Warum ist binäre Suche schneller als lineare Suche?

Die lineare Suche prüft Werte nacheinander. Die binäre Suche verwirft bei jedem Vergleich ungefähr die Hälfte des verbleibenden Bereichs. Das funktioniert nur bei passend sortierten Daten.

Ist Bubble Sort ein schlechter Algorithmus?

Er ist für große Datenmengen meist ineffizient, aber didaktisch sehr wertvoll, weil Vergleiche, Vertauschungen, Schleifen und Laufzeit gut sichtbar werden. Der Einsatzzweck entscheidet über die Bewertung.

Was bedeutet O(n²)?

Der Aufwand wächst vereinfacht quadratisch mit der Eingabegröße. Verdoppelt sich n, kann sich der dominante Arbeitsaufwand ungefähr vervierfachen. Konkrete Laufzeiten hängen zusätzlich von Implementierung und Umgebung ab.

Was ist wichtiger: Laufzeit oder Speicher?

Das hängt vom Projekt ab. Manche Systeme haben knappe Rechenzeit, andere knappen Speicher. Häufig existiert ein Zielkonflikt, bei dem mehr Speicher eine schnellere Verarbeitung ermöglicht oder umgekehrt.

Wie lerne ich Algorithmen am besten?

Formuliere kleine Probleme in Pseudocode, führe jeden Schritt mit Papier und Stift aus, teste Grenzfälle und implementiere die Lösung anschließend. Vergleiche erst danach alternative Verfahren und ihre Kosten.

Was ist der Unterschied zwischen Greedy und dynamischer Programmierung?

Greedy trifft lokale Entscheidungen und hofft auf globale Optimalität. Dynamische Programmierung berechnet alle Teillösungen und kombiniert sie optimal. Greedy ist schneller, aber nicht immer korrekt.

Wann verwende ich Backtracking?

Backtracking wird verwendet, wenn alle möglichen Lösungen durchsucht werden müssen – z.B. bei Rätseln (Sudoku, N-Damen), Graphenproblemen oder bei der Suche nach optimalen Konfigurationen.

Datenschutz-Übersicht
digitale-start-hilfe.de

Auf dieser Website werden Cookies verwendet, um deine Nutzererfahrung zu verbessern. Du kannst in den {setting}Einstellungen{/setting} mehr erfahren oder Cookies jederzeit ablehnen.

Eine vollständige Liste aller Cookies findest du in unserer Cookie-Erklärung.

Weitere Informationen findest du in unserer Datenschutzerklärung.

Notwendige Cookies & Chatbot

Diese Cookies sind für den Betrieb der Website unbedingt erforderlich und können nicht deaktiviert werden. Dazu gehören auch grundlegende Funktionen wie der WebChatAgent (Chatbot) von WebChatAgent.com, der die direkte Kommunikation mit uns ermöglicht.