二分法-时间复杂度(简单)

题目描述:

有个长度为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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值