二分查找的高效在于,每一步都可以去除当前区间中的一半元素,因此这种算法的时间复杂度是$O(logn)$
二分的前提是该序列是有次序的,例如递增或递减
//序列中是否存在满足某条件的元素 int binarySearch(int A[],int left,int right,int x) { int mid; while(left<=right) //作为元素不存在的判定原则,因此left<=right满足时应当一直执行,当left>right是则不再是闭区间 { mid = left+(right-left)/2; //避免left+right溢出范围 if(A[mid] == x) return mid; else if(A[mid] > x) right = mid-1; else if(A[mid] < x) left = mid+1; } return -1; // 返回-1表示查找失败 }
int lower_bound(int A[],int left,int right,int x) { int mid; while(left<right) { mid = left+(right-left)/2; //避免left+right溢出范围 if(A[mid] >= x) // 返回第一个大于等于x的元素的位置 right = mid; else left = mid+1; } return left; // 此时left==right,即应该存在的位置 }
int upper_bound(int A[],int left,int right,int x) // 返回第一个大于x的元素的位置 { int mid; while(left<right) { mid = left+(right-left)/2; //避免left+right溢出范围 if(A[mid] <= x) left = mid+1; else right = mid; } return left; // 此时left==right,即应该存在的位置 }
如果想要找最后一个满足条件A的元素的位置,则可以先求第一个满足条件!A的元素的位置,然后再减一。