zoukankan      html  css  js  c++  java
  • 关于二分查找法的思考

     一,

      这是最常见的二分查找法了。就是在一次次的排除中,让头和尾相遇。若头反超了尾,还没有找到,那就是没有了,否则位于头尾之间的中一定可以取到想要的数据

    //并不是一定要中间值,只是中间值比较快,差个1也可以
    #define MAX 100000
    int a[MAX] = { 0 };
    void FindNum(int data)
    {
        int tou = 0, wei = MAX - 1;
        int flag = -2;  //标记有没有找到 data
        int count = 0;   //记录是第几次查找
        while (tou <= wei)
        {
            int zhong = (tou + wei) / 2;
            printf("tou=%d,wei=%d,zhong=%d,count=%d
    ", tou, wei, zhong, ++count);
            if (data == a[zhong])
            {
                printf("看zhong,找到了%d
    ",a[zhong]);
                flag = 1;
                break;
            }
            else if (data > a[zhong])
            {
                tou = zhong + 1;
            }
            else
                wei = zhong - 1;        
        }
        if (flag == -2)
            printf("找不到
    ");
    }
    int main(void)
    {
        for (int i = 0; i < MAX ; i++)   //要查找的数组,1~MAX
        {
            a[i] = i;
        }
        int data;
        while (scanf("%d", &data) != EOF)
        {
            FindNum(data);
        }return 0;
    }

    二,

      先概述一下下面这个二分法吧。

      1,此法判断不了有没有找到数据,最后判断还是要因题而异,自己判断。

      2,if 执行的那条语句 就是最后找到的data。

    #define MAX 100000
    int a[MAX] = { 0 };
    void FindNum(int data)
    {
        int tou = 0, wei = MAX - 1;
        int flag = -2;  //标记有没有找到 data
        int count = 0;   //记录是第几次查找
        while (tou <= wei)
        {
            int zhong = tou + (wei - tou) / 2;
            printf("tou=%d,wei=%d,zhong=%d,count=%d
    ", tou, wei, zhong, ++count);
            if (a[zhong]< data)   // 也可以换成 >,只是后面的都要换
                tou = zhong + 1;
            else
                wei = zhong - 1;
        }
        printf("看tou,找到%d了
    ", tou);
    }
    int main(void)
    {
        for (int i = 0; i < MAX; i++)
        {
            a[i] = i;
        }
        int data;
        while (scanf("%d", &data) != EOF)
        {
            FindNum(data);
        }return 0;
    }

      之前一直无法理解为什么这样子也可以用二分法,不过我最后一次次尝试,终于想到一个不追究过程,就可以看出循环后 tou和wei在哪里的方法。

      

    三,

      下面这个可以说是二的应用了:查询小于等于x且下标最大的数字的下标

    这个也可以用上面方法画出结果来。

    #define N (int)1e5+5
    int a[N], n;
    int findU(int data)
    {
        int L = -1, R = n;
        while (L + 1 < R)
        {
            int mid = L + (R - L) / 2;
            if (a[mid] <= data)    //这个也可换成 >,L与R 换一下,还是 return L,效果不变
                L = mid;
            else
                R = mid;
        }
        return L;
    }
    int main(void)
    {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        int x;
        while (scanf("%d", &x) != EOF)
        {
            printf("下标为%d
    ", findU(x));
        }
        system("pause");
        return 0;
    }

      最终有几种情况 (因为已经说了判断不出来是否找不找的到)

      当然这个换一下也可以找大于等于x且下标最小的数字的下标,具体的还是不去多讲,给大家留下思考的空间。

    综上就是现在的我对二分法的理解了。共勉之!

    ========== ========== ======== ======= ====== ====== ==== === == =

    问刘十九  白居易 唐

    绿蚁新醅酒,红泥小火炉。

    晚来天欲雪,能饮一杯无?

  • 相关阅读:
    C++ using namespace std详解
    FlexEdit强大的文本编辑器(免费的!)
    串口扩展方案总结
    LED数码引脚图
    串口扩展方案总结
    C++ using namespace std详解
    Digital Mars Compiler简介及使用
    Digital Mars Compiler简介及使用
    poj1018
    poj3536
  • 原文地址:https://www.cnblogs.com/asdfknjhu/p/12143727.html
Copyright © 2011-2022 走看看