二分算法深入理解及代码实现!

首先,什么是二分查找呢?它是一种高效率查找算法,也称折半查找。为什么说效率高呢?让我们举个例子,A同学随便在心里想一个数,然后B同学来猜这个数,如果按照做普通的方法从1~1000便利找的话,最慢的情况会猜1000次,而如果用二分思想的话,不管他想的是什么数,B都能在10次之内猜到。(首先猜500,除了运气特别好直接猜对外不管A说太大还是太小,B都继续把可行范围缩小一半:如果太大,那么答案在1~499之间,如果太小,则在501~1000之间。只要每次选择可行区间的中点去猜,每次都能把范围缩小一半。由于log2(1000)<10,10次之内一定能猜到)
二分查找的重要条件:要查找的序列一定是单调的
递归算法举例

#include<bits/stdc++.h>
using namespace std;
int binarySearch(int a[],int l,int r,int key){
    if (l<=r){
        int mid=(l+r)>>1;
        if (a[mid]==key) return mid;
        else if (a[mid]>key) return binarySearch(a,l,mid-1,key);
        else return binarySearch(a,mid+1,r,key);
    }
    return -1;  //没有找到返回-1
}
int main(){
    int a[5]={1,3,5,6,7};
    cout<<binarySearch(a,0,4,5)<<endl;//找到5的序号为2
}

迭代实现

#include<bits/stdc++.h>
using namespace std;
int binarySearch(int a[],int l,int r,int key){
     while(l<=r){
        int mid=(l+r)>>1;
        if (a[mid]==key) return mid;
        else if (a[mid]>key) r=mid-1;
        else l=mid+1;
    }
    return -1;  //没有找到返回-1
}
int main(){
    int a[5]={1,3,5,6,7};
    cout<<binarySearch(a,0,4,7)<<endl;//找到7的序号为4
}

尽管能用递归实现,但一般都不用递归形式的二分写法。
下面介绍一种c++STL函数库里的二分,lower_bound(),upper_bound()binary_search().(STL里的各种数据结构真的是很实用,建议各位花些功夫学好这些)

binary_search():函数模板 :binary_search(arr[], arr[]+size , indx)。
参数说明:arr[]:数组首地址。
size:数组元素个数。
index:需要查找的值。
函数功能: 在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则返回1,若查找不到则返回值为0。
示例:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[5]={1,3,5,6,7};
    cout<<binary_search(a,a+5,6)<<endl;
    //找到6,返回1
}

lower_bound() :函数功能: 函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置。

upper_bound():
函数功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置。

例:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[10]={1,3,3,5,6,7,7,8,10,12};
    cout<<lower_bound(a,a+10,3)-a<<' ';
    cout<<upper_bound(a,a+10,3)-a<<' ';
    cout<<lower_bound(a,a+10,7)-a<<' ';
    cout<<upper_bound(a,a+10,7)-a<<' ';
}
//输出:1 3 5 7

二分原理易懂然而也要在刷题中慢慢提升自己对二分

下面附上一道题吧

/*问是否有x满足这个等式: 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,x属于[0,100],可以为分数
,保留四位小数
*/
#include <iostream>
#include<stdio.h>
using namespace std;
int calculate(int x)
{
    return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6;
}
int main()
{
    int y;
    double high=100,low=0,mid;
    while(cin>>y)
    {
        while(low-high<1.0e-6)            / /循环至high,low近乎相等
        {
            mid=(high+low)/2;
            if(calculate(mid)<y)
                low=mid;
            else
                high=mid;
        }
        printf("%.4lf\n",high);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codedz/article/details/78802003