一个整数数组A[n]已排序,在数组中查找一个值为val的数,若存在则返回该数在数组中的位置k,有以下四个问题:
1. 数组由小到大排列时,要求k最靠左
2. 数组由小到大排列时,要求k最靠右
3. 数组由大到小排列时,要求k最靠左
4. 数组由大到小排列时,要求k最靠右
这四个问题用线性扫描搜索解决很简单,但如果用二分法如何正确的搜索呢?以下给出这四个问题的解答,注意差异,感兴趣的读者可以自己分析一下为什么会有这些差异。
int binsearch_leftmost_asc(int key, int arr[], int len) { int left = 0; int right = len - 1; int mid; while(left <= right) { //不用(left + right)/2 以免计算left+right时溢出 mid = left + (right - left) / 2; //向左取整 if(key > arr[mid]) left = mid + 1; else right = mid - 1; } if(key == arr[left]) return left; return -1; } int binsearch_leftmost_asc(int key, int arr[], int len) { int left = 0; int right = len - 1; int mid; while(left < right) { //注意微妙差异 mid = left + (right - left) / 2; if(key > arr[mid]) left = mid + 1; else right = mid; } if(key == arr[left]) return left; return -1; } int binsearch_leftmost_desc(int key, int arr[], int len) { int left = 0; int right = len - 1; int mid; while(left <= right) { mid = left + (right - left) / 2; if(key < arr[mid]) left = mid + 1; else right = mid - 1; } if(key == arr[left]) return left; return -1; } int binsearch_rightmost_asc(int key, int arr[], int len) { int left = 0; int right = len - 1; int mid; while(left < right) { mid = left + (right - left + 1) / 2; //向右取整 if(key < arr[mid]) right = mid - 1; else left = mid; } if(key == arr[left]) return left; return -1; } int binsearch_rightmost_desc(int key, int arr[], int len) { int left = 0; int right = len - 1; int mid; while(left < right) { mid = left + (right - left + 1) / 2; if(key > arr[mid]) right = mid - 1; else left = mid; } if(key == arr[left]) return left; return -1; }
浙公网安备 33010602011771号