二分搜索

二分法有点类似于数学中的零点定理

如果单调直线区间左右异号,那么零点一定在这个区间内

二分检测的思想就是吧原数组的起点和终点当作区间的界,然后找中点,如果中点元素大于要找的数字,且数组是升序数组,那么中点就变成了右界,反之,重点变成左界,循环操作,直到左右界重合

 

代码

#include<iostream>

using namespace std;

int BinarySearch(int* Arr, int ArrLen, int Target);

int main(void)
{
    int ArrLen;
    cin >> ArrLen;

    int* Arr = new int[ArrLen];
    for (int i = 0; i < ArrLen; ++i)
        cin >> Arr[i];

    int Target;
    cin >> Target;

    cout << BinarySearch(Arr, ArrLen, Target) << endl;

    system("pause");
    return 0;
}

int BinarySearch(int* Arr, int ArrLen, int Target)
{
    int L = 0;
    int R = ArrLen - 1;
    while (L <= R)
    {
        int Mid = L + (R - L) / 2;// 防止溢出
        if (Arr[Mid] == Target)
            return ++Mid;

        if (Arr[Mid] < Target)
            L = Mid + 1;
        if (Arr[Mid] > Target)
            R = Mid - 1;
    }
    return -1;
}

 

二分查找是一个比较简单的算法,但是有一些细节需要注意

1.二分查找是根据数组下标来计算的,所以他的右界时ArrLen-1,不是ArrLen

2.while循环的条件是左<=右,因为左界等于右界的时候也要进行判断

3.为什么左右界变化的时候要用mid-1或者mid+1?相当于做了一个开区间操作,这样做是为了加快速度,因为mid位置的元素已经不满足要求了,所以就直接跳过他了,如果数组中有重复元组,找最左边或者最右边的,可以去掉对应的+1,相当于做了个闭区间操作

4.求中点Mid不用(L+R)/2而是用L+(R-L)/2是因为防止两个32位数相加溢出

 

posted @ 2020-10-29 15:06  Wangtn  阅读(104)  评论(0编辑  收藏  举报