Binary Search เป็นอัลกอริทึมค้นหาใน อาร์เรย์ที่เรียงลำดับแล้ว โดยแบ่งช่วงค้นหาลงครึ่งเรื่อยๆ
เงื่อนไข
- อาร์เรย์ต้อง เรียงลำดับแล้ว (Sorted)
- เข้าถึงแบบ Random Access ได้ (Array, Vector)
หลักการทำงาน
- ตั้งค่า
low = 0,high = n-1 - คำนวณ
mid = (low + high) / 2 - เปรียบเทียบ
arr[mid]กับค่าที่หา (target) - ถ้าเท่ากัน → หาเจอ คืนค่า index
- ถ้า target น้อยกว่า → ค้นหาครึ่งซ้าย (
high = mid - 1) - ถ้า target มากกว่า → ค้นหาครึ่งขวา (
low = mid + 1) - ทำซ้ำจน
low > high(ไม่เจอ)
โค้ด Recursive Version
#include <iostream>
using namespace std;
int binarySearch(int arr[], int low, int high, int target) {
if (low > high)
return -1; // ไม่เจอ
int mid = low + (high - low) / 2; // ป้องกัน overflow
if (arr[mid] == target)
return mid;
else if (arr[mid] > target)
return binarySearch(arr, low, mid - 1, target);
else
return binarySearch(arr, mid + 1, high, target);
}
int main() {
int arr[] = {1, 3, 7, 15, 18, 20, 25, 33, 36, 40};
int n = sizeof(arr) / sizeof(arr[0]);
int target;
cout << "Enter number to search: ";
cin >> target;
int index = binarySearch(arr, 0, n - 1, target);
if (index == -1)
cout << target << " not found in array" << endl;
else
cout << target << " found at index " << index << endl;
return 0;
}
โค้ด Iterative Version (แนะนำ)
int binarySearchIterative(int arr[], int n, int target) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
ผลลัพธ์ตัวอย่าง
Enter number to search: 20 20 found at index 5 Enter number to search: 100 100 not found in array
Complexity
| Metric | Complexity |
|---|---|
| Time - Best | O(1) |
| Time - Average | O(log n) |
| Time - Worst | O(log n) |
| Space (Recursive) | O(log n) |
| Space (Iterative) | O(1) |
Lower Bound / Upper Bound (C++ STL)
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {1, 3, 7, 15, 18, 20, 25, 33, 36, 40};
int target = 20;
// lower_bound: ตำแหน่งแรกที่ >= target
auto itLow = lower_bound(v.begin(), v.end(), target);
// upper_bound: ตำแหน่งแรกที่ > target
auto itUp = upper_bound(v.begin(), v.end(), target);
// binary_search: พบหรือไม่ (bool)
bool found = binary_search(v.begin(), v.end(), target);
// equal_range: คู่ [lower, upper)
auto range = equal_range(v.begin(), v.end(), target);
cout << "Found: " << found << endl;
cout << "Lower bound index: " << (itLow - v.begin()) << endl;
cout << "Upper bound index: " << (itUp - v.begin()) << endl;
cout << "Count of " << target << ": " << (range.second - range.first) << endl;
return 0;
}
ผลลัพธ์ STL
Found: 1 Lower bound index: 5 Upper bound index: 6 Count of 20: 1
Binary Search บนเงื่อนไข (Predicate)
ใช้หาค่า น้อยที่สุดที่ทำให้เงื่อนไขเป็นจริง (Lower Bound on Answer)
// หา x น้อยที่สุดที่ f(x) = true
// f(x) ต้องเป็น monotonic (false...false true...true)
int binarySearchPredicate(int low, int high) {
while (low < high) {
int mid = low + (high - low) / 2;
if (f(mid))
high = mid;
else
low = mid + 1;
}
return low; // หรือ high
}
ข้อผิดพลาดทั่วไป
- ❌
mid = (low + high) / 2→ อาจ Overflow → ใช้low + (high - low) / 2 - ❌ ลืมตรวจสอบ
low <= highใน while loop - ❌ ใช้กับอาร์เรย์ที่ ไม่ได้เรียง
- ❌ คืนค่า
midแทนlowหรือhighในบางรูปแบบ