思想:
(1)二分法,即一分为二的方法。
(2)在一个区间内,用目标数与中间数比较,若目标数大于中间数,则中间数后的一个数与最后一个数组成新区间,再让目标数与新区间的新中间数比较,若目标数小于中间数,则中间数前的一个数与第一个数组成新区间,再让目标数与新区间的新中间数比较,依此类推,直到最新区间的下限大于上限,即区间不成立为止。
C语言代码:
注意:(1)采用二分法之前,需要将数据排好序,此处默认数据是排好序的。
(2)采用二分法时,因研究对象过多,要注意数组下标的使用。
(3)要控制low与high,时刻掌控low与high的情况,他两个关乎循环的进行与否。
(4)注意循环结尾的break,把控break的时机。
(5)flag的数要注意,它才是最终关乎输出的值
#include<stdio.h>
int main()
{
int n, m;
scanf("%d %d", &n, &m);//输入数组的长度和查询的次数
int a[n];//定义数组
int i;
for (i = 0; i < n; i++) {//对数组初始化
scanf("%d", &a[i]);
}
int low = 0, high = n, cnt;
int mid, key,flag;
int s=1;
while (s<=m) {//查询的次数要小于等于m
cnt = 0;
flag=0;
low = 0;
high = n;
scanf("%d", &key);//输入要查询的数
while (low <= high && cnt <= m) {
//二分法:一开始让要查询的数与数组的中间项比较, 如果大于中间项,则把下限改为中间+1项,如果大于中间项,则把上限改为中间-1项,再与后面的中间项比较,逐次与新的中间项比较
mid = (low + high) / 2;
if (key > a[mid]) {//让查询的数与中间项对比,如果大于中间项,则把下限改为中间+1项
low = mid + 1;
}
if (key < a[mid]) {//如果大于中间项,则把上限改为中间-1项
high = mid - 1;
}
if (a[mid] == key) {//如果查询的数刚好为中间值,则找到这个数了
printf("YES\n");
flag=1;//把flag设为1 代表找到数了
break;
}
cnt++;//有查询次数限制,如果限制次数内找不到,则也默认查询数不在数组里
}
if(flag==0){//如果没找到数,则flag为0,就输出no
printf("NO\n");
}
s++;
}
return 0;
}