二分搜索
二分法有点类似于数学中的零点定理
如果单调直线区间左右异号,那么零点一定在这个区间内
二分检测的思想就是吧原数组的起点和终点当作区间的界,然后找中点,如果中点元素大于要找的数字,且数组是升序数组,那么中点就变成了右界,反之,重点变成左界,循环操作,直到左右界重合
代码
#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位数相加溢出
无情的摸鱼机器