二分查找

二分查找

  • 给一个长为 n 的序列 。查找 x 是否存在,若存在,输出下标和查找次数,否则输出 -1 。

思路:单纯的查找就行了,一旦找到就跳出循环。

撸代码:

 1#include<stdio.h>
2#include<string.h>
3int main()
4
{
5    int n,a[1010];
6    scanf("%d",&n);
7    for(int i=1;i<=n;i++)
8    {
9        scanf("%d",&a[i]);
10    }
11    int x;
12    scanf("%d",&x);
13    int l=1,r=n,mid;
14    int sum=0;
15    while(l<=r)
16    {
17        sum++;
18        mid=(l+r)>>1;
19        if(a[mid]==x)//一旦找到跳出
20            break;
21        else if(a[mid]>x)
22            r=mid-1;
23        else if(a[mid]<x)
24            l=mid+1;
25    }
26    if(a[mid]==x)//a[mid]即为答案
27        printf("%d ",l-1);
28    else
29        printf("-1 ");
30    printf("%d ",sum);
31    return 0;
32}
  • 若存在多个 x 呢?我要输出第一个大于等于x 的数字。

思路:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z7u4AXUM-1589184490175)(C:UsersAdministratorAppDataRoamingTypora	ypora-user-imagesimage-20200511155615089.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z7u4AXUM-1589184490175)(C:UsersAdministratorAppDataRoamingTypora ypora-user-imagesimage-20200511155615089.png)]

mid 指向 x 的中间,那么想一下,既然 x 存在,要找 x 最左边的数,所以一定变化的是 R 指针;那么 R=mid 还是 R=mid-1 呢?

显然是 R=mid ,因为万一 mid 左边的值不是 x 怎么办?不至于丢了这个已经找到的 x 。那么 L 该怎么变呢?若 mid >x , L=mid+1 ,就好啦。

撸代码:

 1#include<stdio.h>
2#include<string.h>
3int main()
4
{
5    int n,a[1010];
6
7    scanf("%d",&n);
8    for(int i=1;i<=n;i++)
9    {
10        scanf("%d",&a[i]);
11    }
12    int x;
13    scanf("%d",&x);
14    int l=1,r=n,mid;
15    int sum=0;
16    while(l<r)
17    {
18        mid=(l+r)/2;
19        if(a[mid]<x)
20            l=mid+1;
21        else
22            r=mid;
23    }
24    printf("a[%d]=%d ",r,a[r]);
25    return 0;
26}
27/**
28测试样例:
29
308
311 3 5 5 5 6 7 8
325
33
348
351 3 5 5 5 6 7 8
364
37
38*/

原文地址:https://www.cnblogs.com/HappyKnockOnCode/p/12871314.html