二分查找(入门)

二分查找(渣新入门)

二分的写法参考了(http://blog.csdn.net/int64ago/article/details/7425727

下面部分粘贴该博主的博客:

我总结的二分无非就4种情况:YES_LEFT、YES_RIGHT、NO_LEFT、NO_RIGHT,分别代表:能找到且返回最左边的数的位置(如查找4的时候返回位置3)、能找到且返回最右边的数的位置(如查找4的时候返回位置4)、不能找到且返回左边与其接近的数的位置(如查找3的时候返回位置2)、不能找到且返回右边与其接近的数的位置(如查找3的时候返回位置3)。下面是我总结调试的代码:

对于YES_LEFT或者NO_RIGHT

int binaryselect_YLNR(int low, int high, int key)
{
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if(a[mid] >= key)
            high = mid - 1;
        else low = mid + 1;
    }
    return low;
}

对于YES_RIGHT或者NO_LEFT

int binaryselect_YRNL (int low, int high, int key)
{
    while(low <= high)
    {
        int mid = (low+high) / 2;
        if( a[mid] <= key)
            low = mid + 1;
        else high = mid - 1;
    }
    return high;
}

以上是我根据转载的博客的写法自己手打了一遍,对于mid值可以写成 low+(high-low)/2 防爆Int;
我自己对这个写法的理解是:
对于YRNL 或者是 YLNR,(即数组中有重复出现元素), 搜到key值后要寻找边界值,即左边界或右边界,倒数第二步时会越过正确值(+1或者-1),之后else(-1或+1),得到正确值。

对于只有一个元素的查找很容易理解这里就不说了。

下面是测试数据:
输入m, n (m是整数个数,n是查询个数)
m个整数:1, 2,3,3,3,5,6

对于YLNR: 查询1,2,3,4,6(边界值,重复值,不存在值)
输出1,2,3,6,7

对于YRNL: 查询1,2,3,4,6
输出1,2,5,5,7

just的就不写了。。。

以上代码均测试通过。
下面贴代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
int a[100];
using namespace std;

int binaryselect_just(int low, int high, int key)
{
    while(low <= high)
    {
        int mid = (low+high) / 2;
        if(a[mid]==key) return mid;
        else if (a[mid] < key)
            low = mid + 1;
        else high = mid - 1;
    }
}

int binaryselect_YRNL (int low, int high, int key)
{
    while(low <= high)
    {
        int mid = (low+high) / 2;
        if( a[mid] <= key)
            low = mid + 1;
        else high = mid - 1;
    }
    return high;
}

int binaryselect_YLNR(int low, int high, int key)
{
    while (low <= high)
    {
        int mid = (low+high) / 2;
        if(a[mid] >= key)
            high = mid - 1;
        else low = mid + 1;
    }
    return low;
}

int main()
{
    int n,m;
    int key;
    while (scanf("%d%d",&n, &m)!=EOF)
    {
        memset(a, 0, sizeof(a));
        for(int i=0; i<n; i++) scanf("%d",&a[i]);
        sort(a, a+n);

        while(m--)
        {
            scanf("%d",&key);
            printf("%d\n",binaryselect_YRNL(0, n-1, key)+1);
            //printf("%d\n",binaryselect_YLNR(0, n-1, key)+1);
            //printf("%d\n",binaryselect_just(0, n-1, key)+1);
        }

     }
     return 0;
}

如有错误或建议,希望能提出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值