• c#二(三)分查找的两种方式


    其实;两种方式的实现结果一样,却体现出了不同的思考过程;

    地中方式,是在一个while循环中,每次从中间找,不断的去改变low 和 high的 位置,然后求他们的中间位置,知道low=high=0;如果还没有知道值,就直接返回-1;

            /// <summary>
            ///  二分查找方式
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public static int BinaySearch(int[] arr, int target)
            {
                int len = arr.Length;
                int low = 0;
                int high = len - 1;
                //一个while循环就搞定了;
                while (low <= high)
                {
                    int middleIndex = (low + high) / 2;
                    int middleValue = arr[middleIndex];
                    if (middleValue == target)
                    {
                        return middleIndex;
                    }
                    else if (target > middleValue)
                    {
                        //searching in right;
                        low = middleIndex + 1;
                    }
                    else
                    {
                        //searching in left;
                        high = middleIndex - 1;
                    }
                }
                //没有找到直接就return
                return -1;
            }

    然后,是利用我们递归的方式来实现的;如果没有找到,子改变地址,然后recursionly的去searching

            /// <summary>
            ///  这样我们的二分查找的递归方式就出来了;
            ///  这个方式是我们用递归的方式来实现的;
            ///  不同的代码实现过程,体现了你不同的思考过程;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="low"></param>
            /// <param name="high"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public static int RecursionlyBinaySearch(int[] arr, int low, int high, int target)
            {
                int l = low;
                int h = high;
                if (l > h)
                    return -1;
                int middleIndex = (l + h) / 2;
                int middleValue = arr[middleIndex];
                if (middleValue == target)
                {
                    //stop finding;
                    return middleIndex;
                }
                else if (target > middleValue)
                {
                    // finding in right;
                    return RecursionlyBinaySearch(arr, middleIndex + 1, high, target);
                }
                else
                {
                    //finding in left;
                    return RecursionlyBinaySearch(arr, l, middleIndex - 1, target);
                }
    
            }

    本来,想整一个第三种方式出来的;。。。。。。。。。。。只是本来;

    第一种做法,有一个bug,你发现了吗????而且!!!非常不明显;

    详细的,请看这里;

    https://research.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html

    这里还有更详细的介绍:

    https://www.quora.com/Why-do-people-use-mid-low+-high-low-2-instead-of-low+high-2

    ps:有我们的二分查找,当然就有我们的三分查找,四分,等等;如果再分的更细;就形成了我们一个个的查找,这样的意义并不带,因为,我们内部的查找是串行的,如果能够找到内部的查找是并行的;

    那么;这样查找的意义才比较大;

    总之,要做好区间的分割;同样的,我给出;两种实现方式;

    第一种简单的while实现;

            /// <summary>
            ///  这个怎么去分呢???
            ///  分成了三个区间;
            ///  就是一个不断划分区间,然后进行查找的问题;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="target"></param>
            public static int ArrayTernarySearch1(int[] arr, int target)
            {
                //开始;
                int len = arr.Length;
                int low = 0;
                int high = len - 1;
    
                while (low <= high)
                {
                    //计算中间位置;
                    int middle1Index = low + (high - low) / 3;
                    int middle2Index = high - (high - low) / 3;
                    //中间值;
                    int middle1Vaule = arr[middle1Index];
                    int middle2Vaule = arr[middle2Index];
    
                    if (target <= middle1Vaule)  //做好区间分割;
                    {
                        if (target == middle1Vaule)
                        {
                            return middle1Index;
                        }
                        else
                        {
                            high = middle1Vaule - 1;
                        }
                    }
                    else if (middle1Vaule < target && target <= middle2Vaule) //做好区间分割;
                    {
                        if (target == middle2Vaule)
                        {
                            return middle2Index;
                        }
                        else
                        {
                            low = middle1Index + 1;
                            high = middle2Index - 1;
                        }
    
                    }
                    else if (target > middle2Vaule) //做好区间分割;
                    {
                        low = middle2Index + 1;
                    }
    
                }
    
                return -1;
            }

    第二种递归实现;

            /// <summary>
            /// 递归实现;
            /// 加油,我们把这段时间,给熬过去;窝草你尼玛的比;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="low"></param>
            /// <param name="high"></param>
            /// <returns></returns>
            public static int RecursionTernarySearch(int [] arr,int low,int high,int target)
            {
    
                if (low > high)
                    return -1;
    
                int l = low;
                int h = high;
    
                if(l <= h)
                {
                    int m1 = l + (h - l) / 3;
                    int m2 = h - (h - l) / 3;
    
                    int m1Value = arr[m1];
                    int m2Value = arr[m2];
    
                    if (m1Value == target)
                    {
                        return m1;
                    }
                    if (m2Value == target)
                    {
                        return m2;
                    }
    
                    //区间划分; 
                    if (target < m1Value)
                    {
                        RecursionTernarySearch(arr, low, m1 - 1, target);
    
                    }
                    else if (m1Value < target && target < m2Value)
                    {
                        RecursionTernarySearch(arr, m1 + 1, m2 - 1, target);
                    }
                    else
                    {
                        RecursionTernarySearch(arr, m2 + 1, high, target);
                    }
    
                }
    
                return -1;
            }
    
            /// <summary>
            /// 这种方式的思路要清晰一些;
            /// 非常不错,我们一次性就成功的写正确的代码;
            /// 效果非常好;
            /// </summary>
            /// <param name="arr"></param>
            /// <param name="target"></param>
            /// <returns></returns>
            public static int TernarySearch(int [] arr,int target)
            {
                int len = arr.Length;
                if (len < 0)
                    return -1;
               int index=RecursionTernarySearch(arr, 0, len - 1,target);
                return index;
            }

    当然,还有我们的四分;和五分。。。。但这样分下去,就没有多大的意义;

  • 相关阅读:
    CString to char*
    修改mfc中的图标的问题
    MFC Class Wizard要到这里来找
    多文档情形下,窗口的重绘
    64位的ubuntu跑不了32位下编译出来的代码,可是我就是想跑啊
    ubuntu不能执行某个执行文件,这个叫权限不够
    碰到了在ubuntu下不能读windows盘符的问题——ubuntu使用心得
    画个多边形来,CDC
    如果要在mFC客户区添加控件怎么办
    饿汉单例模式实例——取快递
  • 原文地址:https://www.cnblogs.com/mc67/p/8297597.html
Copyright © 2020-2023  润新知