二分查找
二分查找适用于查找有序数组中是否存在某个元素,通过每次折半的思想可以节省很多时间。例如猜数字游戏。每次我们猜中间值。能直接排除一半的错误答案。
int main(){ int arr[]={1,2,3,4,5,6,7,8,9}; int ans; scanf("%d",&ans); int start=0,end=sizeof(arr)/sizeof(arr[0])-1,mid=-1; while (start<=end) { mid=start+end>>1; if (arr[mid]>ans) { end=mid-1; }else if (arr[mid]<ans) { start=mid+1; /* code */ }else{ break; } /* code */ } if (mid==-1) { printf("没找到"); /* code */ }else{ printf("下标为%d",mid); } }
这种方法适用与数组相同元素为0的情况。如果数组存在相同元素。那么返回的下标会变得不确定。有可能是任意一个下标. 所以要改变策略
找最左边的下标
int main(){ int n,mid; int q[]={-2,-1,1,2,3,3,5,6,7,8,9,10,11,12}; scanf("%d",&n); int l=0,r=sizeof(q)/sizeof(q[0])-1; while(l<r){ //防止边界问题 mid=l+r+1>>1; if(q[mid]<=n)l=mid; else r=mid-1; } printf("%d",l); return 0; }
找最右边的下标
int main(){ int n,mid; int q[]={-2,-1,1,2,3,3,5,6,7,8,9,10,11,12}; scanf("%d",&n); int l=0,r=sizeof(q)/sizeof(q[0])-1; while(l<r){ int mid=l+r>>1; if(q[mid]>=n)r=mid; else l=mid+1; } printf("%d",l); return 0; }