Binary search
Masalah
Cari posisi target di array yang sudah terurut, lebih cepat daripada memeriksa satu per satu.
Input / Output
- Input: array terurut
a(panjangn), nilaitarget - Output: indeks
idengana[i] == target, atau-1kalau tidak ada
Ide utama
Bandingkan target dengan elemen tengah. Karena array terurut, separuh bagian yang tidak mungkin berisi target bisa dibuang setiap langkah.
Langkah
- Set
kiri = 0,kanan = n - 1. - Selama
kiri <= kanan, ambiltengah = kiri + (kanan - kiri) / 2. - Kalau
a[tengah] == target, kembalikantengah. - Kalau
a[tengah] < target, geserkiri = tengah + 1. Kalau tidak,kanan = tengah - 1. - Kalau loop selesai tanpa ketemu, kembalikan
-1.
Flowchart
flowchart TD
mulai([Mulai]) --> init[kiri = 0, kanan = n - 1]
init --> loop{kiri <= kanan?}
loop -- tidak --> gagal[/return -1/]
loop -- ya --> mid["tengah = kiri + floor((kanan - kiri) / 2)"]
mid --> eq{"a[tengah] == target?"}
eq -- ya --> ok[/return tengah/]
eq -- tidak --> lt{"a[tengah] < target?"}
lt -- ya --> kanan_[kiri = tengah + 1]
lt -- tidak --> kiri_[kanan = tengah - 1]
kanan_ --> loop
kiri_ --> loop
ok --> selesai([Selesai])
gagal --> selesai
Status rentang pencarian
stateDiagram-v2 [*] --> Rentang: kiri=0, kanan=n-1 Rentang --> Ketemu: a[tengah] == target Rentang --> Rentang: buang separuh Rentang --> Kosong: kiri > kanan Ketemu --> [*] Kosong --> [*]
Pseudocode
fungsi binarySearch(a, target):
kiri = 0
kanan = panjang(a) - 1
selama kiri <= kanan:
tengah = kiri + (kanan - kiri) div 2
jika a[tengah] == target: kembalikan tengah
jika a[tengah] < target: kiri = tengah + 1
selain itu: kanan = tengah - 1
kembalikan -1
Kompleksitas
- Waktu: O(log n), rentang terbelah dua setiap iterasi
- Ruang: O(1)
Edge case
- Array kosong:
kanan = -1, loop tidak jalan, hasil-1 -
targetlebih kecil dari elemen pertama atau lebih besar dari terakhir - Elemen duplikat: versi ini mengembalikan salah satu indeks, bukan yang paling kiri
- Overflow: pakai
kiri + (kanan - kiri) / 2, bukan(kiri + kanan) / 2
Contoh jalan (trace)
a = [2, 5, 8, 12, 16, 23, 38], target = 23
| Langkah | kiri | kanan | tengah | a[tengah] | Keputusan |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 12 | 12 < 23, kiri = 4 |
| 2 | 4 | 6 | 5 | 23 | ketemu, return 5 |
Lihat juga Mulai di sini.