二分查找(折半查找)

•简单定义:在一个单调有序的集合中查找元素,每次将集合分为左右两部分,判断解在哪个部分中并调整集合上下界,重复直到找到目标元素。
•时间复杂度: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

 

posted on 2015-03-22 15:39  kylehz  阅读(140)  评论(0)    收藏  举报