起初对于有序数列查找指定的元素,我们通常采用循环遍历的方法其时间复杂度为O(n),空间复杂度为O(1)。例如在有序数列{1,2,3,4,5}中,查找元素的值为3所在的位置,我们要从下标为0开始遍历所有的数值,当元素的值为3时返回元素所在的下标。
但是,这种方法的时间复杂度较高,所以这时引入二分查找的思想,设置左边界left,右边界right,中间元素的下标mid,通过比较mid与目标值的大小,来变化区间。
1.寻找指定元素的下标:
对于数组num[8] = {1,2,2,2,3,4,5,6}
查找数值为4的下标。
#include <iostream>
using namespace std;
int Binary_Search(int num[],int target){
int left = 0, right = 7;
//当left > right 就无法构成闭区间,可以允许left == right,不然数组长度为1时,二分法无法检测数组里的内容
while(left <= right){
//寻找中间点的下标,如果直接用(left + right)/2,当数值较大时容易造成数值溢出
int mid = left + ((right - left)>>1);
if(num[mid] < target) left = mid + 1;
else if(num[mid] > target) right = mid - 1;
else return mid;
}
//如果没有找到目标数值,输出-1
return -1;
}
int main()
{
int num[8] = {
1,2,2,2,3,4,5,6};
int target = 4;
int index = Binary_Search(num, target);
cout<<index;
}
最后输出下标:5
符合要求。
2.寻找数列中第一个大于或等于目标值的元素的下标:
对于数组num[8] = {1,2,2,2,3,4,5,6}
查找第一个大于或等于目标值为2的元素下标。
方法1:直接使用二分法
#include <iostream>
using namespace std;
int Binary_Search(int num[],int target){
int left = 0, right = 7