NOIP和CSP初赛中通常都会出二分查找的题目,那么,什么是二分查找呢?
二分查找是一种算法,它用于查找一个有序递增数列中的一个数,使用这种算法可以大大减少遍历的时间,方便于查找。那么二分查找是怎么实现的呢?
比如,有一个有序递增数列:1 2 3 4 5
通常使用二分查找的时候会定义三个变量:lbound(左边界)、rbound(右边界)、mid(求中位数)。我们先用mid求这个有序递增数列的中位数。
这个有序递增数列的中位数是3,左边界初始化为1,右边界初始化为数的数量(在次有序递增数列里为5),此时就可以开始二分查找了。
假如要查找2,那么我们先用2跟中位数mid比较,发现2小了,说明要查找的数在整个数列的左边,右边没有要查找的数,故可以把右边界设为中位数,继续查找。此时,左边界还是为1,右边界为mid(中位数),中位数mid变成了2,用2跟中位数2比较,发现相同,说明已经找到了要查找的数,输出该数在整个序列中的位置(中位数mid)。
那么我们来总结一下刚刚的查找过程:
整个查找只用了2次就找到了要查找的数,如果用传统查找法(就是依次遍历数列),在最坏的情况下要遍历n次。由此可见,二分查找非常方便。同时,我们发现了一个规律,求中位数可以使用一个公式(左边界 + 右边界)/ 2。
学习了二分查找的过程,来做做这道题试试水:
100以内查找一个数最坏的情况下使用二分查找需要几次(向上取整)?( )
A.5 B.6 C.7 D.8
正确答案是C,因为是向上取整,所以除以2得到小数后应省略小数再加1。100除以2得50,50除以2得25,25除以2向上取整得13,13除以2向上取整得7,7除以2向上取整得4,4除以2得2,2除以2得1。此时,查找结束,一共是7次。所以,100以内查找一个数最坏的情况下使用二分查找需要7次。
那么怎样用C++代码打二分查找呢?
把基础的代码先打好:
#include <iostream>
#include <algorithm>
using namespace std;
int main (void)
{
ios::sync_with_stdio(false);
long n = 0, x = 0;
int a[1000010] = {0};
cin >> n;
for (long i = 1; i <= n; i++) cin >> a[i];
cin >> x;
//二分查找代码
return 0;
}
接下来到二分查找的核心代码,这里我把左边界lbound简化为l,把右边界rbound简化为r,中位数mid不变:
while(l<=r){
//满足条件再查找
mid=(l+r)/2;//利用公式求中位数
if(a[mid]==x){//如果找到了要查找的数
cout<<mid;//输出该数在数列中的位置
return 0;//程序结束
}
else if(a[mid]<x){
//如果小于中位数就把左边界设为中位数加1
l=mid+1;
}
else{
//如果小于中位数就把右边界设为中位数减1
r=mid-1;
}
}
打完这些代码后,还有一个情况,就是如果要查找的数不在这个数列里怎么办。直接在二分查找函数外输出-1完事。
以上是二分查找知识点的详细解说,希望能对读者起作用。