İkili Arama
Son güncelleme
İkili arama, **sıralı** bir dizide hedef değeri arama penceresini tekrar tekrar yarıya indirerek bulur. Ortadaki elemanı hedefle karşılaştırır: eşleşme aramayı bitirir; aksi halde hedefi içeremeyecek yarı atılır ve pencere diğer yarıya küçülür. Her karşılaştırma kalan elemanların yarısını eler; bu yüzden O(log n) sürede çalışır — bir milyon sıralı değer arasında arama en fazla yaklaşık 20 karşılaştırma gerektirir.
Yukarıdaki animasyon lo, mid ve hi işaretçilerini gösterir ve her karşılaştırmadan sonra elenen yarıyı soluklaştırır. Tek tartışılmaz ön koşul: dizi zaten sıralı olmalıdır — sırasız veride önce doğrusal arama veya bir sıralama gerekir (merge sort sayfasına bakın). Aynı yarıya indirme fikri ikili arama ağacının da temelidir.
Zaman ve alan karmaşıklığı
| Durum | Karmaşıklık | Notlar |
|---|---|---|
| En iyi durum | O(1) | İlk karşılaştırmada ortadaki eleman hedeftir. |
| Ortalama durum | O(log n) | Her karşılaştırma kalan pencereyi yarıya indirir. |
| En kötü durum | O(log n) | Pencere, eşleşme veya başarısızlıktan önce tek bir elemana kadar küçülür. |
| Alan | O(1) | Yinelemeli sürüm yalnızca lo, hi ve mid indekslerini tutar. |
Adım adım
| Adım | Ne olur |
|---|---|
| 1 | lo değerini sıralı dizinin ilk indeksine, hi değerini son indeksine ayarlayın. |
| 2 | Orta indeksi hesaplayın: mid = (lo + hi) // 2. |
| 3 | a[mid] hedefe eşitse mid değerini döndürün — bulundu. |
| 4 | a[mid] hedeften **küçükse**, hedef yalnızca sağ yarıda olabilir: lo = mid + 1 yapın. |
| 5 | a[mid] hedeften **büyükse**, sol yarıyı arayın: hi = mid - 1 yapın. |
| 6 | lo <= hi olduğu sürece 2. adımdan itibaren tekrarlayın; pencere boşalırsa hedef dizide yoktur. |
Çözümlü örnek
[1, 2, 3, 5, 7, 8, 9] dizisinde 5 aranıyor:
| Geçiş | Pencere (lo..hi) | mid | a[mid] | İşlem |
|---|---|---|---|---|
| 1 | [1, 2, 3, 5, 7, 8, 9] (0..6) | 3 | 5 | a[3] = 5 — hedef 3. indekste bulundu. |
Bulunamayan bir arama, adım adım
Aynı dizide 4 aramak pencerenin nasıl boşaldığını gösterir:
| Geçiş | Pencere (lo..hi) | mid | a[mid] | İşlem |
|---|---|---|---|---|
| 1 | 0..6 | 3 | 5 | 5 > 4 — sol yarıyı ara, hi = 2. |
| 2 | 0..2 | 1 | 2 | 2 < 4 — sağ yarıyı ara, lo = 2. |
| 3 | 2..2 | 2 | 3 | 3 < 4 — lo 3 olur, pencere boşalır: bulunamadı. |
İkili arama ne zaman kullanılmalı
| Şu durumlarda kullanın | Şu durumlarda kaçının |
|---|---|
| Veri zaten sıralıysa (veya üzerinde birçok kez arama yapıyorsanız) | Veri sırasızsa ve yalnızca bir kez aranıyorsa — önce sıralamak O(n log n) tutar |
| Koleksiyon hızlı rastgele erişimi destekliyorsa (diziler) | Yalnızca sıralı erişiminiz varsa (bağlı listeler) |
Veri kümesi büyükse — O(log n) büyük ölçekte parlar | Veri kümesi çok küçükse — basit bir tarama aynı hızda ve daha basittir |
Binary Search kodu
Python, JavaScript, Java, C++, C, Pseudocode dillerinde temiz ve çalıştırılabilir bir Binary Search uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.
Python ile Binary Search kodu
1def binary_search(a, target):2 lo, hi = 0, len(a) - 13 while lo <= hi:4 mid = (lo + hi) // 25 if a[mid] == target:6 return mid7 if a[mid] < target:8 lo = mid + 1 # search the right half9 else:10 hi = mid - 1 # search the left half11 return -112
13
14nums = [1, 2, 3, 5, 7, 8, 9] # must be sorted15print("Index of 5:", binary_search(nums, 5))16print("Index of 4:", binary_search(nums, 4))JavaScript ile Binary Search kodu
1function binarySearch(a, target) {2 let lo = 0;3 let hi = a.length - 1;4 while (lo <= hi) {5 const mid = Math.floor((lo + hi) / 2);6 if (a[mid] === target) return mid;7 if (a[mid] < target) {8 lo = mid + 1; // search the right half9 } else {10 hi = mid - 1; // search the left half11 }12 }13 return -1;14}15
16const nums = [1, 2, 3, 5, 7, 8, 9]; // must be sorted17console.log("Index of 5:", binarySearch(nums, 5));18console.log("Index of 4:", binarySearch(nums, 4));Java ile Binary Search kodu
1public class Main {2 static int binarySearch(int[] a, int target) {3 int lo = 0;4 int hi = a.length - 1;5 while (lo <= hi) {6 int mid = (lo + hi) / 2;7 if (a[mid] == target) return mid;8 if (a[mid] < target) {9 lo = mid + 1; // search the right half10 } else {11 hi = mid - 1; // search the left half12 }13 }14 return -1;15 }16
17 public static void main(String[] args) {18 int[] nums = {1, 2, 3, 5, 7, 8, 9}; // must be sorted19 System.out.println("Index of 5: " + binarySearch(nums, 5));20 System.out.println("Index of 4: " + binarySearch(nums, 4));21 }22}C++ ile Binary Search kodu
1#include <iostream>2#include <vector>3
4int binarySearch(const std::vector<int>& a, int target) {5 int lo = 0;6 int hi = static_cast<int>(a.size()) - 1;7 while (lo <= hi) {8 int mid = lo + (hi - lo) / 2;9 if (a[mid] == target) return mid;10 if (a[mid] < target) {11 lo = mid + 1; // search the right half12 } else {13 hi = mid - 1; // search the left half14 }15 }16 return -1;17}18
19int main() {20 std::vector<int> nums = {1, 2, 3, 5, 7, 8, 9}; // must be sorted21 std::cout << "Index of 5: " << binarySearch(nums, 5) << "\n";22 std::cout << "Index of 4: " << binarySearch(nums, 4) << "\n";23 return 0;24}C ile Binary Search kodu
1#include <stdio.h>2
3int binary_search(const int a[], int n, int target) {4 int lo = 0;5 int hi = n - 1;6 while (lo <= hi) {7 int mid = lo + (hi - lo) / 2;8 if (a[mid] == target) return mid;9 if (a[mid] < target) {10 lo = mid + 1; /* search the right half */11 } else {12 hi = mid - 1; /* search the left half */13 }14 }15 return -1;16}17
18int main(void) {19 int nums[] = {1, 2, 3, 5, 7, 8, 9}; /* must be sorted */20 int n = sizeof(nums) / sizeof(nums[0]);21 printf("Index of 5: %d\n", binary_search(nums, n, 5));22 printf("Index of 4: %d\n", binary_search(nums, n, 4));23 return 0;24}Pseudocode ile Binary Search kodu
1DECLARE nums : ARRAY[1:7] OF INTEGER2DECLARE n : INTEGER3n ← 74// The array must be sorted for binary search5nums[1] ← 16nums[2] ← 27nums[3] ← 38nums[4] ← 59nums[5] ← 710nums[6] ← 811nums[7] ← 912
13FUNCTION binarySearch(target : INTEGER) RETURNS INTEGER14 DECLARE lo : INTEGER15 DECLARE hi : INTEGER16 DECLARE mid : INTEGER17 lo ← 118 hi ← n19 WHILE lo <= hi DO20 mid ← (lo + hi) DIV 221 IF nums[mid] = target THEN22 RETURN mid23 ENDIF24 IF nums[mid] < target THEN25 // Target is larger — search the right half26 lo ← mid + 127 ELSE28 // Target is smaller — search the left half29 hi ← mid - 130 ENDIF31 ENDWHILE32 RETURN -133ENDFUNCTION34
35OUTPUT "Index of 5 is ", binarySearch(5)36OUTPUT "Index of 4 is ", binarySearch(4)İkili Arama SSS
İkili aramanın zaman karmaşıklığı nedir?
O(log n), çünkü her karşılaştırma kalan arama penceresini yarıya indirir; ilk ortadaki eleman hedef olduğunda en iyi durumda O(1). Yinelemeli sürüm O(1) ek alan kullanır.İkili arama neden sıralı bir dizi gerektirir?
İkili arama ile doğrusal arama arasındaki fark nedir?
O(n)) ve her dizide çalışır; ikili arama sıralı bir dizinin arama penceresini yarıya indirir (O(log n)) ama sıralı girdi gerektirir. Bir avuç eleman için fark önemsizdir — büyük ölçekte ikili arama açık ara kazanır.İkili arama kaç karşılaştırmaya ihtiyaç duyar?
log2(n) + 1: 10 karşılaştırma 1.000 elemanı, 20 karşılaştırma 1.000.000 elemanı kapsar. Bu logaritmik büyüme, onu sıralı veride varsayılan arama yöntemi yapar.İkili aramadaki klasik taşma (overflow) hatası nedir?
(lo + hi) / 2 olarak hesaplamak, lo + hi türün üst sınırını aştığında sabit boyutlu tamsayılarda taşmaya yol açabilir. Güvenli biçim mid = lo + (hi - lo) / 2 şeklindedir. Python'da bu önemli değildir (keyfi hassasiyetli tamsayılar), ama Java/C/C++ dillerinde gerçek ve ünlü bir hatadır.