Alle Tabs der Lerneinheit (Erklärung · Interaktiv · Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Erklärung
Binäre Suche halbiert bei jedem Schritt den Suchraum, indem sie das mittlere Element prüft und entscheidet ob der Suchwert davor oder danach liegt. Funktioniert nur auf sortierten, effizient indexierbaren Datenstrukturen wie Arrays (bei LinkedLists ist der Indexzugriff selbst O(n)). Du lernst hier die Halbierungs-Logik mit low/mid/high-Variablen-Trace, die Komplexität lceil log₂(n+1) rceil Vergleiche im Worst Case (egal ob Element gefunden wird oder nicht), die Overflow-Falle bei mid = (low + high) / 2 und die sichere Alternative mid = low + (high - low) / 2, die Abbruchbedingung while (low <= high) und warum bei n=1024 im Worst Case bzw. bei erfolgloser Suche bis zu 11 Prüfungen möglich sind (lceil log₂(1025) rceil = 11) und bei erfolgreichem Treffer weniger, plus die Bibliotheks-Varianten lower_bound/upper_bound (C++) bzw. bisect_left/bisect_right (Python) für erstes/letztes Vorkommen bei Duplikaten.
Was du in der Klausur können musst:
- Idee: mittleres Element anschauen, Suchwert kleiner = links weitersuchen, größer = rechts, gleich = gefunden
- Komplexität: O(log n) im Worst- und Average-Case, O(1) im Best-Case
- Voraussetzung: Array muss sortiert sein, sonst funktioniert es nicht
- Anwendung: bei großen sortierten Datenmengen (1 Mio Einträge → ca. 20 Vergleiche statt 500.000)
In Klausuren oft gefragt: dokumentiere die Suche Schritt für Schritt für ein gegebenes Array und einen Suchwert. Schreibe pro Iteration die aktuellen low/high/mid-Indizes auf, das ist die Standard-Aufgabenform.
Die Idee
Stell dir vor, du suchst eine Seite in einem Wörterbuch:
Du schlägst nicht Seite 1 auf und blätterst durch. Du schlägst in der Mitte auf, schaust ob das gesuchte Wort davor oder dahinter steht, und wiederholst das Halbieren.
Das ist binäre Suche. Bei jeder Halbierung verringert sich die Suchmenge um 50%, daher die Komplexität O(log n).
Voraussetzung: sortiert
Binäre Suche funktioniert nur auf sortierten Arrays. Ist das Array unsortiert:
- einzelne Suche: meist linear suchen (eine
O(n)-Suche ist günstiger alsO(n log n)Sortieren). - viele Suchen auf demselben Array: einmaliges Sortieren
O(n log n)amortisiert sich, danachk · O(log n)pro weitere Suche.
Inline-Trace für Target 23 (sortiertes 10er-Array)
Bevor wir den Code anschauen, das Halbierungs-Prinzip in der Mini-Tabelle. Array [2, 5, 9, 14, 18, 23, 27, 31, 36, 42] (Indizes 0..9), Target 23:
| Iter | low | mid | high | arr[mid] | Aktion |
|---|---|---|---|---|---|
| 1 | 0 | 4 | 9 | 18 | 18 < 23 → low = 5 |
| 2 | 5 | 7 | 9 | 31 | 31 > 23 → high = 6 |
| 3 | 5 | 5 | 6 | 23 | Treffer, return 5 |
Drei Vergleiche bei n = 10. Worst Case wäre lceil log₂ 11 rceil = 4.
Implementierung
public static int binarySearch(int[] arr, int target) {
int lo = 0;
int hi = arr.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}Java: lo/hi markieren den aktuellen Suchbereich. mid wird halbiert berechnet (lo + (hi-lo)/2 statt (lo+hi)/2 zur Vermeidung von Integer-Overflow).
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
if arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1Python: identische Logik. Integer-Overflow ist bei Python kein Problem, daher genügt (lo+hi)//2.
Komplexität
Bei jeder Iteration halbiert sich der Suchraum:
n → n/2 → n/4 → n/8 → dots → 1
Wie oft kann man n halbieren bis man bei 1 ankommt? Größenordnung log₂ n. Exakt im Worst Case (auch bei "nicht gefunden") sind es lceil log₂(n+1) rceil Vergleiche bzw. lfloor log₂ n rfloor + 1 bei vorhandenem Treffer.
| n | Maximale Vergleiche lceil log₂(n+1) rceil |
|---|---|
| 16 | 5 |
| 1.024 | 11 |
| 1.000.000 | 20 |
| 1 Mrd. | 30 |
Bei einer Milliarde Einträgen reichen 30 Vergleiche, das ist die Magie von O(log n). Faustregel in Klausuren: ungefähr log₂ n.
Eigenschaften
- ✅ Sehr effizient: O(log n) wächst sehr langsam und skaliert auch bei Millionen Einträgen gut.
- ✅ Skaliert auch bei Millionen: 30 Vergleiche reichen bei 1 Mrd. Elementen
- ❌ Verlangt sortiertes Array: einmaliges Sortieren kostet O(n log n)
- ❌ Nicht für verkettete Listen: braucht Random-Access in O(1)
Klausur-Trace: binäre Suche Schritt für Schritt
Die Standard-Klausuraufgabe lautet: "Gegeben das sortierte Array, gesucht ist Target x. Trage low, high und mid pro Iteration ein." Wir gehen drei Varianten durch.
Beispiel A: Treffer in der Mitte (Best Case)
Array [1, 4, 7, 9, 12, 15, 18] (Indizes 0..6), gesucht Target 9.
| Iter | low | high | mid | arr[mid] | Aktion |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 9 | Treffer, return 3 |
Ein einziger Vergleich. Best Case O(1).
Beispiel B: Treffer am Rand (typischer Fall)
Gleiches Array, gesucht Target 15.
| Iter | low | high | mid | arr[mid] | Aktion |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 9 | 9 < 15 → low = mid+1 = 4 |
| 2 | 4 | 6 | 5 | 15 | Treffer, return 5 |
Zwei Vergleiche. Bei n=7 wären lceil log₂(8) rceil = 3 Vergleiche der Worst Case.
Beispiel C: Target nicht im Array (erfolglose Suche)
Gleiches Array, gesucht Target 6.
| Iter | low | high | mid | arr[mid] | Aktion |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 9 | 9 > 6 → high = mid-1 = 2 |
| 2 | 0 | 2 | 1 | 4 | 4 < 6 → low = mid+1 = 2 |
| 3 | 2 | 2 | 2 | 7 | 7 > 6 → high = mid-1 = 1 |
Jetzt ist low (2) > high (1), die while-Bedingung low <= high ist verletzt → return -1. Drei Vergleiche, das ist der Worst Case bei n=7.
Achtung Klausur: bei n=1024 sind im Worst Case bzw. bei erfolgloser Suche bis zu 11 Prüfungen möglich (lceil log₂(1025) rceil = 11), bei erfolgreichem Treffer können es weniger sein.
Rekursiv vs. iterativ
Die obige Implementierung ist iterativ. Rekursiv sieht es so aus:
public static int bsRecursive(int[] arr, int target, int lo, int hi) {
if (lo > hi) return -1;
int mid = lo + (hi - lo) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) return bsRecursive(arr, target, mid + 1, hi);
return bsRecursive(arr, target, lo, mid - 1);
}
In der Klausur wird oft die iterative Variante verlangt, weil sie keinen Rekursionsstack braucht. Beide Varianten haben identische Komplexität O(log n), die iterative aber O(1) Zusatzspeicher gegen O(log n) Rekursionsstack bei der rekursiven Form.
Duplikate
Die Standard-Variante findet irgendeinen passenden Index, nicht zwingend den ersten oder letzten. Für erstes Vorkommen → lower_bound / bisect_left; für letztes Vorkommen → upper_bound / bisect_right.
Wann sinnvoll?
- Bei großen sortierten Arrays: hier ist binäre Suche deutlich besser als lineare Suche. Für sehr viele exakte Lookups können Hash-Strukturen mit durchschnittlich
O(1)noch besser sein, dafür ohne sortierte Traversierung. - Bei vielen Suchanfragen: einmal sortieren, dann beliebig oft binär suchen
- Bei Datenbank-Indizes: B-Bäume/B+-Bäume nutzen sortierte Schlüssel und eine logarithmische Baumstruktur. Innerhalb eines Knotens kann je nach Implementierung linear oder binär gesucht werden, der Hauptvorteil kommt aus der hohen Verzweigung und der geringen Baumhöhe, nicht aus der binären Suche pro Knoten.
Bibliotheken:
- Java:
Arrays.binarySearch()undCollections.binarySearch()setzen sortierte Daten voraus, bei unsortierten Daten ist das Ergebnis undefiniert. Bei Duplikaten ist nicht garantiert, welcher passende Index zurückgegeben wird. - Python:
bisectliefert primär Einfügepositionen in sortierten Listen (bisect_left,bisect_right). Für Existenzprüfung danach:pos < len(a) and a[pos] == target. - C++:
std::binary_searchliefert nurbool. Für die Position:std::lower_bound(erstes Element≥Target).
Interaktiv
Binäre Suche live
Beobachte wie sich der Suchbereich halbiert. Der orange Highlight markiert das aktuelle Mittelpunkt-Element. Werte außerhalb des Suchbereichs werden ausgegraut.
Probier folgendes:
- Setz das Target auf einen Wert genau in der Mitte: 1 Vergleich (Best Case)
- Setz das Target auf einen Wert außerhalb des Arrays:
lceil log₂(n+1) rceilVergleiche (Worst Case) - Größenordnung: bei n=16 ungefähr 4–5 Vergleiche, bei n=32 ungefähr 5–6
Halt fest: jede Verdopplung der Eingabe kostet nur einen zusätzlichen Vergleich.
Interaktive Visualisierung
Vergleicht lineare und binäre Suche mit Schritt-Counter pro Algorithmus.
Faustregel zum Mitnehmen: Binäre Suche skaliert logarithmisch. Bei 1 Million Einträgen reichen ~20 Vergleiche, bei 1 Milliarde ~30. Linear bräuchte 1 Million bzw. 1 Milliarde.
Code-Stepper: Binäre Suche mit low/mid/high
Wir suchen die 23 im sortierten Array [2, 5, 9, 14, 18, 23, 27, 31, 36, 42] (10 Elemente). Du siehst wie sich low und high nach jedem Vergleich auf eine Seite verschieben, und der Suchbereich halbiert sich. Maximal lceil log₂(11) rceil = 4 Vergleiche.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Quiz
Klausurfragen mit Lösungen (6)
- F1.Welche Komplexität hat die binäre Suche?
Antwort: O(log n)
Erklärung: Bei jeder Iteration halbiert sich der Suchraum: n → n/2 → n/4 → ... → 1. Das ist exakt die Definition von O(log n).
- F2.Welche Voraussetzung hat die binäre Suche?
Antwort: Das Array muss sortiert sein
Erklärung: Binäre Suche funktioniert nur auf sortierten Arrays. Sonst kann man nicht entscheiden, ob das Target links oder rechts vom Pivot liegt.
- F3.Bei einem sortierten Array mit 1.000.000 Elementen: wie viele Vergleiche braucht binäre Suche maximal?
Antwort: Etwa 20
Erklärung: Exakt für Worst Case: `lceil log₂(n+1) rceil`, bei n = 1.000.000 ist das 20. Faustregel: `log₂ n`. Bei 1 Milliarde reichen entsprechend nur 30 Vergleiche.
- F4.Welche Berechnung des Mittelpunkt-Index ist in Java sicher gegen Integer-Overflow?
Antwort: Variante B
Erklärung: In Java kann (lo+hi) bei sehr großen Indizes über Integer.MAX_VALUE laufen. lo + (hi-lo)/2 ist mathematisch äquivalent, vermeidet aber den Overflow. In Python irrelevant, da Python Integer beliebig groß werden können.
- F5.Du hast ein unsortiertes Array mit 1000 Elementen und willst einmal binär suchen. Lohnt sich das?
Antwort: Nein, sortieren kostet O(n log n), das ist langsamer als ein einzelner linearer Scan
Erklärung: Sortieren kostet O(n log n), eine lineare Suche kostet nur O(n). Bei einer einzigen Suche lohnt sich der Sortier-Aufwand nicht. Bei vielen Suchen auf demselben Array sieht es anders aus: einmal sortieren, dann beliebig oft binär suchen.
- F6.Wie viele Vergleiche braucht binäre Suche maximal in einem sortierten Array mit 1024 Elementen (Worst Case, z. B. erfolglose Suche)?
Antwort: 11
Erklärung: Exakt `lceil log₂(1025) rceil = 11` Vergleiche im Worst Case. `log₂(1024) = 10` ist die Anzahl der **Halbierungs-Stufen**, aber im Standard-Code mit `while (lo <= hi)` und erfolgloser Suche braucht man bis zu einem Vergleich mehr. Faustregel: ungefähr `log₂ n`, exakt `lceil log₂(n+1) rceil`.
Typ: Zahlen-Eingabe
// Variante A:
int mid = (lo + hi) / 2;
// Variante B:
int mid = lo + (hi - lo) / 2;