概念:
二分查找就是折半查找,叫法不一样而已,一个东西。
实现逻辑:
LOOP
{
判断arr[mid]是否等于目标?
- 是:查找成功;跳出循环
- 否:重新定义边界;继续循环
}
成功&失败时机
- 成功时机:break跳出循环,此时必然查找成功
- 失败时机:循环自然结束,此时必然失败
查找一次的时间复杂度:
O(log n)
两种实现方式:
-
实现1:调用C++自带的二分查找算法
-
实现2:自定义符合要求的二分查找算法,不需要递归
/*
要求:序列已经有序
本质:不断地一分为二
输入:
5
1 2 3 4 5
3
2 5 7
输出:
YES
YES
NO
*/
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
//预先定义全局数组存储序列
int arr[100];
//二分查找函数 输入:低位、高位、目标值 返回:true/false
bool BSearch(int low,int high,int target)
{
//标志位用于返回函数值,默认为false,查找成功置为true
bool flag = false;
//每次循环都是一次判定
//成功:直接接返回true
//失败:重新确定左右边界
while(low <= high)
{
//mid要求向下取整,在C语言中“/”刚好符合要求
int mid = (low + high)/2;
//成功:mid位置刚好存储目标值
if(target == arr[mid])
{
flag = true;
break;
}
//失败1:目标值在mid左边
else if(target < arr[mid])
{
high = mid - 1;
}
//失败2:目标值在mid右边
else
{
low = mid + 1;
}
}
//至此,flag取值有两种情况
//情况一:查找成功,跳出循环,flag = true
//情况一:查找失败,log(n)次循环,flag = false
return flag;
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 0;i < n;++i)
{
scanf("%d",&arr[i]);
}
int m;
scanf("%d",&m);
//初始化
//low = 数据起始位置
//high = 数据结束位置
int low = 0;
int high = n - 1;
//因为查找m个数据,所以进行m次循环
for(int i = 0;i < m;++i)
{
int target;
scanf("%d",&target);
if(BSearch(low,high,target))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}