二分搜索原理看似都懂,可是真的讓我敲起來,我還真不敢保證寫的必定沒有bug,甚至陷入bug裏不知道怎麼改呢.
其實,二分法真的不是那麼簡單,尤爲是二分的各個變種.下面一次介紹各類變種二分法,而且加上個人總結吧.數組
在一個排好序的數組裏查找一個key值.code
int search(int *arr, int n, int key) { int left = 0, right = n-1; while(left<=right) { int mid = left + ((right - left) << 1); if (arr[mid] == key) return mid; else if(arr[mid] > key) right = mid - 1; else left = mid + 1; } return -1; }
若是條件變化成, 數組中的數據可能重複,要求範圍等於key值最小的下標,或者找出數組中第一個大於(或等於)key值的元素下標,請看下面ast
int searchFirstEqual(int *arr, int n, int key) { int left = 0, right = n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] >= key) right = mid - 1; else if(arr[mid] < key) left = mid + 1; } if( left < n && arr[left] == key) return left; return -1; }
int searchLastEqual(int *arr, int n, int key) { int left = 0, right = n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] > key) right = mid - 1; else if(arr[mid] <= key) left = mid + 1; } if( right>=0 && arr[right] == key) return right; return -1; }
int searchFirstEqualOrLarger(int *arr, int n, int key) { int left=0, right=n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] >= key) right = mid-1; else if (arr[mid] < key) left = mid+1; } return left; }
int searchFirstLarger(int *arr, int n, int key) { int left=0, right=n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] > key) right = mid-1; else if (arr[mid] <= key) left = mid+1; } return left; }
int searchLastEqualOrSmaller(int *arr, int n, int key) { int left=0, right=n-1; while(left<=right) { int m = (left+right)/2; if(arr[m] > key) right = m-1; else if (arr[m] <= key) left = m+1; } return right; }
int searchLastSmaller(int *arr, int n, int key) { int left=0, right=n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] >= key) right = mid-1; else if (arr[mid] < key) left = mid+1; } return right; }
int search(int *arr, int n, int key) { int left=0, right=n-1; while(left<=right) { int mid = (left+right)/2; if(arr[mid] /****/ key) right = mid-1; else if (arr[mid] /****/ key) left = mid+1; } return /****/; }
其中除了3處/****/以外,其餘部分能夠說是模板,很簡短,用的時候敲出來就好了模板
說到這裏,咱們的返回值和等號加在哪裏,2個問題都解決了,就能夠寫完美的二分法啦!
原理