Halbieren statt durchsehen
Ein Hotel speichert die Nummern seiner belegten Zimmer aufsteigend sortiert. Ist Zimmer 135 belegt? Ein Blick in die Mitte verrät, in welcher Hälfte man weitersuchen muss.
- Voraussetzung:die Reihung ist sortiert — sonst sagt die Mitte nichts über die Hälften.
- Suchbereich:die Indizes von
linksbisrechts; zu Beginn 0 bis Länge − 1. - Mitte:
mitte = (links + rechts) / 2mit ganzzahliger Division, z. B. \((0 + 10) / 2 = 5\), \((6 + 7) / 2 = 6\). - Treffer:
a[mitte] = x— Indexmittezurückgeben. - Zu klein:
a[mitte] < x— rechts weitersuchen:links ← mitte + 1. - Zu groß:
a[mitte] > x— links weitersuchen:rechts ← mitte − 1. - Abbruch:gilt
links > rechts, ist der Bereich leer — Rückgabe −1.
static int binaereSuche(int[] a, int x) {
int links = 0;
int rechts = a.length - 1;
while (links <= rechts) {
int mitte = (links + rechts) / 2; // ganzzahlige Division
if (a[mitte] == x) {
return mitte;
} else if (a[mitte] < x) {
links = mitte + 1; // x kann nur rechts liegen
} else {
rechts = mitte - 1; // x kann nur links liegen
}
}
return -1; // Bereich leer: links > rechts
}
Tracetabelle und Aufwand
Aufruf binaereSuche(zimmer, 135). Als ein Vergleich zählt jeder Blick auf a[mitte].
| Vergleich | links | rechts | mitte | zimmer[mitte] | Entscheidung |
|---|---|---|---|---|---|
| 1 | 0 | 10 | 5 | 126 | 126 < 135 → links ← 6 |
| 2 | 6 | 10 | 8 | 141 | 141 > 135 → rechts ← 7 |
| 3 | 6 | 7 | 6 | 130 | 130 < 135 → links ← 7 |
| 4 | 7 | 7 | 7 | 135 | gefunden → gib 7 zurück |
- Ergebnis:Index 7 nach 4 Vergleichen — die lineare Suche bräuchte 8.
- Ohne Treffer:die Suche nach 110 endet mit
links = 2 > rechts = 1und liefert −1, ebenfalls nach 4 Vergleichen. - Halbieren:jeder Vergleich ohne Treffer schließt die Mitte und eine ganze Hälfte aus.
Du steuerst die Suche selbst: Vergleiche das markierte Element in der Mitte mit dem gesuchten Wert und entscheide, welche Hälfte bleibt — die andere wird weggelegt. Klicke dazu in die Hälfte oder nutze die Pfeiltasten. Achte auf die Grenzen links, rechts und mitte.
| Nr. | links | rechts | mitte | a[mitte] | Entscheidung |
|---|
Halte fest: Jeder Vergleich halbiert den Suchbereich mindestens — bei 15 Elementen ist nach spätestens 4 Vergleichen Schluss, bei 16 nach spätestens 5.
Herleitung:Vor dem ersten Vergleich umfasst der Suchbereich alle \(n\) Elemente.
Jeder Vergleich ohne Treffer lässt höchstens die Hälfte übrig — nach \(k\) Vergleichen also höchstens so viele Elemente.
Ein weiterer Vergleich findet nur statt, solange noch mindestens ein Element im Bereich liegt.
Beide Seiten mit \(2^k\) multiplizieren.
Da \(k\) ganzzahlig ist, gilt höchstens \(k = \lfloor\log_2 n\rfloor\) — so oft kann man ohne Treffer halbieren.
Dazu kommt der letzte Vergleich im Bereich mit einem Element. Beispiel: \(n = 11\) ergibt \(\lfloor 3{,}46\rfloor + 1 = 4\).
Binäre Suche in einer sortierten Reihung: höchstens \(\lfloor\log_2 n\rfloor + 1\) Vergleiche · Abbruch ohne Treffer bei links > rechts
Allgemeine Hinweise
Immer mitte ± 1
Mit links = mitte; statt mitte + 1 bleibt der Bereich bei zwei Elementen gleich groß — die Schleife läuft endlos. Die Mitte ist nach dem Vergleich erledigt und gehört nicht mehr dazu.
Unsortiert? Erst sortieren
Auf einer unsortierten Reihung liefert die binäre Suche falsche Ergebnisse, ohne abzustürzen. Prüfe vorher, ob die Daten sortiert sind — sonst lineare Suche oder erst sortieren.
Doppelte Werte
Kommt x mehrfach vor, liefert die binäre Suche irgendeines der Vorkommen — nicht unbedingt das erste. Wer das erste braucht, muss nach einem Treffer links weitersuchen.
