Vorlesung 12 | Fortgeschrittene Algorithmen
Von O(n) zu O(log n) - ein gewaltiger Unterschied!
Problem: Bei 1 Million Elementen → bis zu 1 Million Vergleiche!
Suche nach "Müller" im Telefonbuch mit 500.000 Namen:
Starten bei "A"...
Blättern... Blättern... Blättern...
Bis zu 500.000 Namen prüfen!
Öffne in der Mitte → "L"
"Müller" > "L" → rechte Hälfte
Öffne Mitte der rechten Hälfte...
Nur ~19 Schritte!
Divide and Conquer: In jedem Schritt halbieren wir den Suchbereich!
links = linke Grenze (anfangs 0)rechts = rechte Grenze (anfangs n-1)mitte = mittlerer Indexmitte = links + (rechts - links) / 2
mitte mit der Formelarr[mitte] mit gesuchtem Wertrechts = mitte - 1links = mitte + 1links <= rechtsAbbruch: Wenn links > rechts → Element nicht gefunden! (Suchbereich ist leer)
Schritt 1: links=0, rechts=8 → mitte = 0 + (8-0)/2 = 4, arr[4] = 17
23 > 17 → rechte Hälfte
Schritt 2: links=5, rechts=8 → mitte = 5 + (8-5)/2 = 6, arr[6] = 31
23 < 31 → linke Hälfte
Schritt 3: links=5, rechts=5 → mitte = 5 + (5-5)/2 = 5, arr[5] = 23
23 == 23 → Gefunden an Index 5!
Nur 3 Schritte statt bis zu 9 bei linearer Suche!
links + (rechts - links) / 2?(links + rechts) / 2Problem: Overflow bei großen Arrays!
Wenn links = 2 Milliarden und rechts = 2 Milliarden:
links + rechts = 4 Milliarden → Overflow!
int kann nur bis ~2.1 Milliarden
links + (rechts - links) / 2Mathematisch identisch, aber:
(rechts - links) ist immer ≤ n
Kein Overflow möglich!
Immer diese Variante verwenden!
Beispiel: links = 0, rechts = 8
1. rechts - links = 8 - 0 = 8
2. (rechts - links) / 2 = 8 / 2 = 4
3. links + 4 = 0 + 4 = 4
→ mitte = 4 ✓
|←──────────────── Distanz: 8 ────────────────→|
|←────── halbe Distanz: 4 ──────→|
Startpunkt + halbe Distanz = Mitte
Warum sicher? (rechts - links) ist immer kleiner als (rechts + links), daher kein Overflow!
8 Elemente
↓ ÷ 2 (Schritt 1)
4 Elemente
↓ ÷ 2 (Schritt 2)
2 Elemente
↓ ÷ 2 (Schritt 3)
1 Element ✓
3 Halbierungen → 3 Schritte
16 → 8 → 4 → 2 → 1
4 Halbierungen → 4 Schritte
1024 → 512 → 256 → 128 → 64 → 32 → 16 → 8 → 4 → 2 → 1
10 Halbierungen → 10 Schritte
Formel: Anzahl Schritte = log₂(n)
log₂(8) = 3, weil 2³ = 8 | log₂(16) = 4, weil 2⁴ = 16 | log₂(1024) = 10, weil 2¹⁰ = 1024
Die O-Notation beschreibt, wie die Laufzeit eines Algorithmus mit der Eingabegröße n wächst.
Konstant - Array-Zugriff, Variable lesen
Logarithmisch - Binäre Suche
Linear - Lineare Suche, Array durchlaufen
Quadratisch - Bubble Sort, Selection Sort
Exponentiell - Naive Fibonacci, Brute Force
| Komplexität | Operationen | Bei 1 Op/μs |
|---|---|---|
| O(1) | 1 | 1 μs |
| O(log n) | 20 | 20 μs |
| O(n) | 1.000.000 | 1 Sekunde |
| O(n²) | 10¹² | 11,5 Tage |
| O(2ⁿ) | 10³⁰⁰⁰⁰⁰ | Länger als das Universum! |
Fazit: Je flacher die Kurve, desto besser der Algorithmus!
| n | O(n) | O(log n) |
|---|---|---|
| 8 | 8 | 3 |
| 64 | 64 | 6 |
| 1.000 | 1.000 | 10 |
| 1.000.000 | 1.000.000 | 20 |
Bei 1 Million Elementen:
Linear: 1.000.000 Schritte
Binär: 20 Schritte
50.000× schneller!
Immer 1 Operation, egal wie groß das Array
n Durchläufe → n Operationen
n × n = n² Operationen
Verschachtelte Schleifen!
Suchbereich wird halbiert
Binäre Suche!
O(3n) = O(n), O(100) = O(1)
O(n² + n + 1) = O(n²)
for i... for j... → O(n × m)
O(n) + O(n²) = O(n²)
A) O(n)
B) O(n²)
C) O(n³)
D) O(3n)
Erklärung:
Achtung: Bei n=1000 sind das 1 Milliarde Operationen!
| Eigenschaft | Lineare Suche | Binäre Suche |
|---|---|---|
| Zeitkomplexität | O(n) | O(log n) |
| Voraussetzung | Keine | Array muss sortiert sein |
| Implementierung | Sehr einfach | Etwas komplexer |
| Bei 1 Mio. Elementen | bis 1.000.000 Vergleiche | max. 20 Vergleiche |
Fazit: Wenn Sie oft suchen müssen, lohnt sich Sortieren + binäre Suche!
Buch "K" finden? → Jedes einzeln prüfen!
⏱️ Bis zu 5 Versuche
Buch "K" finden? → Mitte prüfen, dann links/rechts!
⏱️ Nur 2-3 Versuche
💡 Merke: Einmal sortieren = viel schneller suchen!
Wie viele Schritte bei n = 16 Elementen?
1 Schritt
Beispiel: arr[0] lesen
4 Schritte
Binäre Suche
16 Schritte
Lineare Suche
O(n²) bei n=16? → 256 Schritte! 😱
Verwende wenn:
Verwende wenn:
Sortieren + Binär:
🎯 Faustregel: Bei mehr als ~10 Suchen im gleichen Array → sortieren lohnt sich!
Lösung: Erst sortieren!
Merke: <= nicht vergessen!
Teste immer mit:
Array: [2, 4, 7, 10, 15, 20] | Gesucht: 7
Schritt 1: links=0, rechts=5, mitte=(0+5)/2=2
arr[2] = 7 == 7? JA! Gefunden!
Nur 1 Schritt! Bei linearer Suche wären es 3 Schritte gewesen.
Wörter alphabetisch sortiert → Binäre Suche nach Wort
O(log n)
Punkte sortiert → Schnell Position finden
O(log n)
Indizes sind sortiert → Schnelle Suche nach ID
O(log n)
1. Was ist die Zeitkomplexität der binären Suche?
→ O(log n)
2. Was ist die wichtigste Voraussetzung?
→ Array muss sortiert sein!
3. Wie viele Vergleiche bei 1 Million Elementen?
→ Max. 20 Vergleiche (log₂(1.000.000) ≈ 20)
4. Was bedeutet O(n²)?
→ Verdoppelt sich n, vervierfacht sich die Zeit
🎉 Herzlichen Glückwunsch! 🎉
Sie haben jetzt alle wichtigen Konzepte der Fortgeschrittenen Programmierung gelernt!
Viel Erfolg bei der Prüfung! 💪