🧮 Algorithmen verstehen
Probleme in klare, ausführbare Schritte zerlegen – mit Pseudocode, Such- und Sortierverfahren, verständlicher Laufzeitanalyse und interaktiven Übungen.
🛠️ 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.
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.
Eindeutig
Jeder Schritt ist so genau beschrieben, dass er nicht unterschiedlich ausgelegt werden muss.
Ausführbar
Alle Einzelschritte können mit den verfügbaren Mitteln tatsächlich durchgeführt werden.
Endlich
Für zulässige Eingaben endet die Ausführung nach einer begrenzten Zahl von Schritten.
Korrekt
Für den vorgesehenen Eingabebereich entsteht das fachlich richtige Ergebnis.
Allgemein
Die Lösung funktioniert nicht nur für ein einzelnes Beispiel, sondern für eine definierte Problemklasse.
Nachvollziehbar
Aufbau, Annahmen und Entscheidungen sind verständlich dokumentiert und testbar.
3. Eingabe – Verarbeitung – Ausgabe
Das EVA-Prinzip hilft, ein Problem in drei übersichtliche Bereiche zu zerlegen.
Stammkunde: ja
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
EINGABE a, b
WENN a > b DANN
AUSGABE a
SONST
AUSGABE b
ENDE WENN
5. Sequenz, Auswahl und Wiederholung
Sehr viele Algorithmen lassen sich aus drei grundlegenden Kontrollstrukturen zusammensetzen.
Sequenz
Anweisungen werden in festgelegter Reihenfolge nacheinander ausgeführt.
wasser_einfüllen
wasser_erhitzen
kaffee_aufgießenAuswahl
Eine Bedingung entscheidet, welcher Weg ausgeführt wird.
WENN temperatur > 90 DANN
heizung_ausschalten
SONST
weiter_erhitzenWiederholung
Eine Anweisung wird für Werte oder solange eine Bedingung gilt wiederholt.
FÜR jede zahl IN zahlen
summe ← summe + zahl
ENDE FÜR6. 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.
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.
Grundidee
Bei einer Liste mit n Elementen sind im ungünstigsten Fall n Vergleiche nötig.
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.
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.
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
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.
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.
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:
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.
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.
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
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).
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.
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
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.
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.
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
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.
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:
14. Dynamische Programmierung
Dynamische Programmierung löst komplexe Probleme, indem sie sie in überlappende Teilprobleme zerlegt und die Ergebnisse zwischenspeichert (Memoization).
Grundidee
Die dynamische Programmierung eignet sich besonders für Optimierungsprobleme, bei denen die Lösung aus optimalen Teillösungen besteht.
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]
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.
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.
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
16. Backtracking
Backtracking ist eine systematische Suchmethode, die alle möglichen Lösungen durchprobiert und bei Sackgassen zurückspringt.
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.
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.
Grundidee
Diese Strategie wird bei Merge Sort, Quicksort, binärer Suche und vielen anderen effizienten Algorithmen verwendet.
| Algorithmus | Divide | Conquer | Combine |
|---|---|---|---|
| Merge Sort | Liste halbieren | Sortieren | Zusammenführen |
| Quicksort | Partitionieren | Sortieren | – (in-place) |
| Binäre Suche | Mitte finden | In Hälfte suchen | – |
| Karatsuba | Multiplikation aufteilen | Teilprodukte | Kombinieren |
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.
| Klasse | Bezeichnung | Vereinfachtes Beispiel | Wachstum |
|---|---|---|---|
O(1) | Konstant | Element über bekannten Listenindex lesen | Unabhängig von n |
O(log n) | Logarithmisch | Binäre Suche in sortierter Liste | Sehr langsam steigend |
O(n) | Linear | Liste einmal vollständig durchlaufen | Proportional zu n |
O(n log n) | Linear-logarithmisch | Effiziente vergleichsbasierte Sortierung | Meist gut skalierend |
O(n²) | Quadratisch | Viele doppelt verschachtelte Vergleiche | Bei großen n schnell teuer |
O(2ⁿ) | Exponentiell | Naive Untersuchung vieler Teilmengen | Sehr 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.
19. Algorithmen in Python und JavaScript
Lineare Suche in Python
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
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
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]))
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
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
22. Fibonacci-Vergleich: Rekursiv vs. Iterativ
Dieses Labor zeigt den dramatischen Performance-Unterschied zwischen rekursiver und iterativer Implementierung der Fibonacci-Folge.
Fibonacci berechnen
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.
- 1Problem präzisierenWelche Eingaben, Ausgaben und fachlichen Regeln sind verbindlich?
- 2Daten verstehenWie groß sind sie, sind sie sortiert und wie häufig ändern sie sich?
- 3Grenzfälle sammelnLeere Eingabe, doppelte Werte, ungültige Daten und sehr große Mengen berücksichtigen.
- 4Einfache korrekte Lösung bauenVerständlichkeit und Testbarkeit bilden die erste stabile Grundlage.
- 5Messen und vergleichenMit realistischen Daten prüfen, ob Laufzeit oder Speicher tatsächlich problematisch sind.
- 6Gezielt optimierenNur den nachgewiesenen Engpass verbessern und Korrektheit erneut testen.
| Situation | Erste sinnvolle Wahl | Begründung |
|---|---|---|
| Kleine unsortierte Liste, einmalige Suche | Lineare Suche | Einfach und ohne vorheriges Sortieren. |
| Große bereits sortierte Liste | Binäre Suche | Suchbereich wird wiederholt halbiert. |
| Viele Suchvorgänge nach exakten Schlüsseln | Passende indexierte Datenstruktur | Vorbereitung kann sich durch häufige Abfragen lohnen. |
| Sehr kleine oder fast sortierte Liste | Einfaches geeignetes Sortierverfahren | Geringer Verwaltungsaufwand kann wichtiger sein. |
| Große Daten, garantierte Laufzeit | Merge Sort oder Heapsort | O(n log n) garantiert, keine schlechten Fälle. |
| Große Daten, gute Durchschnittsleistung | Quicksort | In 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.
Größten Wert finden
Entwickle einen Algorithmus, der den größten Wert einer nicht leeren Zahlenliste zurückgibt.
Gerade Zahlen zählen
Zähle, wie viele gerade Zahlen in einer Liste enthalten sind.
Lineare Suche erweitern
Gib nicht nur den ersten, sondern alle Indizes eines Zielwertes zurück.
Bubble Sort absteigend
Ändere den Vergleich so, dass die größte Zahl am Anfang steht.
Quicksort implementieren
Implementiere Quicksort in einer Sprache deiner Wahl und teste ihn mit verschiedenen Eingaben.
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.
🧱 Datenstrukturen
Listen, Stapel, Warteschlangen, Mengen, Bäume und Graphen verstehen.
Weiterlernen →🐍 Python für Einsteiger
Algorithmen mit Variablen, Bedingungen, Schleifen und Funktionen umsetzen.
Weiterlernen →🟨 JavaScript für Einsteiger
Logik direkt in interaktive Webseiten und Anwendungen übertragen.
Weiterlernen →🌿 Git & Versionskontrolle
Algorithmus-Varianten sicher entwickeln, vergleichen und dokumentieren.
Weiterlernen →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.
Hinweis: Laufzeitangaben sind vereinfachte Modelle. Prüfe Korrektheit und Leistung immer mit realistischen Daten, Grenzfällen und der tatsächlichen Zielumgebung.