题目描述:
有个长度为n的数组A。由于数组实在太大了,所以经常询问整数x是否在数组A中
输入格式:
第一行输入两个整数n和m,分别表示数组的长度和查询的次数
接下来一行有n个整数ai
接下来m行,每行有1个整数x,表示询问的次数
输出格式:
对于每次查询,如果可以找到,输出“YES”,否则输出“NO”
数据范围:
1<=n,m<=10^5,0<=x<=10^6
输入样例:
10 5
1 1 1 2 3 5 5 7 8 9
0
1
4
9
10
输出样例:
NO
YES
NO
YES
NO
解题思路:使用二分法查找的时候需注意该数组是有序的,一般为升序,所以使用二分法查找时先用快速排序法将其排序,这个方法较省时间
#include <stdio.h>
void quickSort(int arr[], int low, int high); //快速排序函数名
int search(int s[], int n, int x); //二分法查找函数名
//先快速排序,升序
void quickSort(int arr[], int low, int high){
if (low>high){
return;
}
int i=low,j=high,temp=arr[0];//分别得到左右两边的数和基准数且temp为数组中的第一个数
while(i<j) {
while(temp<arry[j]&&i<j){ // 将最后一个数与数组第一个数相比较,若大于第一个数,不动,然后再与倒数第二个数相比较,所以j--
j--;
}
if(i<j){ //若小于第一个数,则互相交换位置
arry[i++]=arry[j];
}
while(temp>arry[i]&&i<j){ //这时将第二个数作为基准数与后面的值相比较,与上相同
i++;
}
if(i<j){
arry[j--]=arry[i];//遇到比第二个数小的数时交换位置
}
}
arry[i]=temp;//直到两数相同时停止
quickSort(arry,low,i-1);//比较过后排序完成
quickSort(arry,i+1,high);
}
//再进行二分法查找(数组一定要有序,所以先用以上快速排序法)
int search(int s[], int n, int x){
int low=0,high=n-1,mid=0; //确定数组边界的最左值和最右值
while(low<=high) {
mid=(low+high)/2; //取数组中间的数值
if(x>s[mid]){ //若查找的数大于s[mid]
low=mid+1; //让数组左边界为mid+1
} else if(x<s[mid]){ //若查找的数小于s[mid]
high=mid-1; //让右边界为mid-1
} else if(s[mid]==x){ //直到找到s[mid]=待查找的数,返回主函数
return 1;
}
}
return 0; //找不到则返回到0
}
int main(){
int n,m,t,c;
scanf("%d %d", &n,&m);
int a[n],i;
for(i=0;i<n;i++){ //将这n个数放入数组,输入n个数值
scanf("%d",&a[i]);
}
i=0;
t=n-1;
quickSort(a,i,t); //使用快速排序对数值进行查找
int k=0;
for(i=0;i<m;i++){
scanf("%d",&c); //输入m个待查找的数
k=search(a,n,c); //使用二分函数,找输入的数是否存在于该数组中
if(k==1){
printf("YES\n");
}
else{
printf("NO\n");
}
}
return 0;
}