二分查找(折半查找)
•简单定义:在一个单调有序的集合中查找元素,每次将集合分为左右两部分,判断解在哪个部分中并调整集合上下界,重复直到找到目标元素。
•时间复杂度:O (logn),优于直接顺序查找O(n)
看图理解查找21的过程

数组的二分查找:
使用二分查找的前提是数组是有序的
下面是递增的情况
int binary_search(int *a,int l,int r,int val) { while(l<r) { int mid=(l+r)/2; if(a[mid]>val)r=mid-1; else if(a[mid]<val)l=mid+1; else return mid; } return -1;//-1表示没有找到 }
如果数组中有相同元素,要找第一个,改版:
比如 2 3 5 5 6 9 ,找5的位置,得到2
int lower_bound(int *a,int l,int r,int val) { while(l<r) { int mid=(l+r)/2; if(a[mid]>=val)r=mid; else l=mid+1; } return r; }
单调函数二分查找:
int fun(int x) { return x*x; } int lower_bound(int l,int r,int val) { while(l<r) { int mid=(l+r)/2; if(fun(mid)>=val)r=mid; else l=mid+1; } return r; }
STL二分查找函数
•头文件 <algorithm>
•binary_search ()
试图在已排序的[first, last)中寻找元素value。如果[first, last)内有等价于value的元素,它会返回true,否则返回false,它不返回查找位置。
•lower_bound()
试图在已排序的[first,last)中寻找元素value。如果[first, last)具有等价于value的元素,lower_bound返回一个iterator指向其中第一个元素。如果没有这样的元素存在,它便返回假设这样的元素存在的话,会出现的位置。即指向第一个不小于value的元素。如果value大于[first, last)的任何一个元素,则返回last。
•upper_bound()
试图在已排序的[first,last)中寻找value,返回可安插value的最后一个合适的位置。如果value存在,lower_bound 返回的是指向该元素的iterator。相较之下upper_bound并不这么做,它返回value可被安插的最后一个合适位置。如果value存在,那么它返回的iterator将指向value的下一个位置,而非value自身。
使用方法参考:
#include<cstdio> #include<algorithm> using namespace std; int main(){ int a[5]={1,3,5,5,7}; printf("%d\n",binary_search(a,a+5,3)); printf("%d\n",lower_bound(a,a+5,5)-a); printf("%d\n",upper_bound(a,a+5,5)-a); return 0; }
练习:http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1508
浙公网安备 33010602011771号