如果要搜尋的資料已經事先排序好, 則可以使用 二元搜尋法 (Binary Search) 來進行搜尋. 二元搜尋法 是將資料分割成兩等份, 再比較鍵值與中間值的大小, 如果鍵值小於中間值, 可以確定要找的資料再前半段的元素, 否則在後半部. 如此分割數次直到找到或確定不存在為止.
二元搜尋法範例說明 :
考慮有已排序序數列 2, 3, 5, 8, 9, 11, 12, 16, 18 而要搜尋值為 11 時 :
Step1 : 首先更第五個數值9 比較, 因為11 > 9, 所以往後半部移動.
Step2 : 接著選擇後半段中間值 12 比較, 因為11 < 12, 所以往前半部移動.
Step3 : 因為前半部只剩下11=11, 表示搜尋完成.
二元法分析 :
範例代碼 (C):
- #include <iostream>
- using namespace std;
- int binarySearch(int data[50], int val){
- int low=0, high=49, mid=0;
- cout << "搜尋處理中..." << endl;
- while(low<=high && val!=-1) {
- mid = (low+high)/2;
- if(val
- high = mid-1;
- cout << val << " 介於 data[" << low << "]=" << data[low] << " 與 data[" << mid << "]" << data[mid] << endl;
- } else if(val>data[mid]) {
- low = mid+1;
- cout << val << " 介於 data[" << mid << "]=" << data[mid] << " 與 data[" << high << "]" << data[high] << endl;
- } else{
- return mid;
- }
- }
- return -1;
- }
- void main() {
- int data[50] = {0}, val=1;
- for(int i=0; i<50; i++) {
- data[i] = val;
- val+=(rand()%5+1);
- }
- int key=0, num;
- while(1) {
- cout << "請輸入搜尋值(1-150), 輸入-1結速: ";
- cin >> key;
- if(key<0)
- break;
- num = binarySearch(data, key);
- if(num>=0) {
- cout << "在第 " << num << "個位置找到 ( data[" << num << "]=" << data[num] << "." << endl;
- } else {
- cout << "##### 沒有找到 " << key << "#####" << endl;
- }
- }
- }
範例代碼 (Python):
Python 的內建 library bisect 可以提供類似 Binary Search 的功能:
Source code link:
- from bisect import bisect_left
- def binary_search(a, x):
- i = bisect_left(a, x)
- if i != len(a) and a[i] == x:
- return i
- else:
- return -1
- # Driver code
- a = [1, 2, 4, 4, 8]
- for v in [1, 4, 5, 0]:
- i = binary_search(a, v)
- if i == -1:
- print("{} is not in list={}!".format(v, a))
- else:
- print("{} is at position {} in list={}".format(v, i, a))
補充說明 :
* Wiki : Binary Search
* [C 範例代碼] 尋找演算法 : 二分查找
* Use Case: HackerRank - Climbing the Leaderboard
沒有留言:
張貼留言