Description
给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始
要求使用折半查找算法
Input
第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,从小到大,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行
1 <= n, t <= 10000
Output
每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error
Sample
#0
Input
Copy
8 11 22 33 44 55 66 77 88 3 22 88 99
Output
Copy
2 8 error
二分查找法:
可以理解为在一个范围里面找值,我们先取一个中间值,如果中间值大于要查找的num,那num肯定在这个中间值的左边,所以右边界就变成此时的中间值。
然后循环重复这个步骤,当循环结束的时候要么找到了,要么就是没找到这个数,因为不一定在数组里.
1.left=0 right=4
2.mid=2
3.shuzu[mid]>num 所以num一定在mid的左边,所有右边界可以换成mid,就是5这个数
4.left=0 right=2
5.mid=1
6.shuzu[mid]==num此时找到了shuzu[mid]<=num,left=mid左边界变成mid
7.while(left<right-1)所以退出循环,此时left刚好是num的下标
然后如果我们这里num2,步骤也差不多,但是我们要判断此时最后的left的下标值是否是num,不是就不存在这个数
二分模板:
全部代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 10;
int shuzu[maxn];
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++)
{
scanf("%d", &shuzu[i]);//输入数组
}
int t;
scanf("%d", &t);//输入查找t次
while (t--)
{
int num;
scanf("%d", &num);//输入查找数num
int left = 0, right = n;
while (left < right - 1)///二分法进行查找
{
int mid = (left + right) / 2;
if (shuzu[mid] <= num)///如果此时shuzu[mid] <= num
{
///说明查找的值在mid右边,所以左边界left=mid
left = mid;
}
else///如果此时shuzu[mid] > num
{
//说明查找的值在mid右边,所以左边界right=mid
right = mid;
}
}
if (shuzu[left] == num)//最后判断下查找的值是否真的相等,因为如果没有查找到的话也会退出循环
{
cout << left + 1 << "\n";
}
else
{
cout << "error" << endl;
}
}
}
return 0;
}