二分法,顾名思义即可
接下来瞅瞅二分法可以做些什么
a[i] | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
left | mid | right |
根据这张表,可知mid把数组分为了两段。
通过两个个标志位left和right,可以计算出mid。
具体方法:
mid = (left + right) /2 (注意是int/int)
下面看看几个简单的算法:
二分查找:时间复杂度 O(logn)
空间复杂度 O(1)
//二分区间为左右封闭的[left,right],传入的初始值[0,n-1]
int binarySearch(int a[],int left,int right,int x){
int mid;
while(left<=right){ //如果left<right就没有办法形成闭区间了
mid=(left+right)/2;//计算mid位置
if(a[mid]==x) return mid;//找到
else if(a[mid]>x){//mid位元素比x大
right=mid-1; //去左边找
}else{ //mid位元素比x小
left=mid+1; //去右边找
}
}
return -1;//没找到返回-1
}//若为递减序列改动判断条件即可
int main(){
int a[10]={1,3,4,6,7,8,10,11,12,15};
printf("%d\n",binarySearch(a,0,9,6));
}
找出第一个大于x元素的位置
时空复杂度同上
//找出第一个大于x的元素
//a[]为递增序列,x为欲查询数,函数返回第一个大于等于x的位置
//二分的上下界为左闭右闭的[left,right],传入初始值为[0,n]
int lowb(int a[],int left,int right,int x){
int mid;
while(left<right){对于[left,right]来说,left==right意味着找到了唯一位置
mid=(left+right)/2;
if(a[mid]>x){
right=mid;
}else{
left=mid+1;
}
}
return left;
}
int main(){
int n,x;
scanf("%d %d",&n,&x);
int a[10];
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
printf("%d",lowb(a,0,n,x));
return 0;
}