二分和三分

在实际应用中,二分法查找常用于寻找单调函数:


二分和三分_第1张图片

而当函数不是单调函数时将会用到三分查找
二分和三分_第2张图片

这时需要用三分查找找到函数的最值,然后使用二分法在单调区域中找到目标值。
以下部分转自:
http://www.cnblogs.com/zhangchenliang/archive/2011/06/14/2081018.html
首先是二分查找法,时间复杂度O(2log2(n)):

        static bool Find(int[] sortedArray, int number)
        {
            if (sortedArray.Length == 0)
                return false;

            int start = 0;
            int end = sortedArray.Length - 1;

            while (end >= start)
            {
                int middle = (start + end) / 2;
                if (sortedArray[middle] < number)
                    start = middle + 1;
                else if (sortedArray[middle] > number)
                    end = middle - 1;
                else
                    return true;
            }
            return false;
        }

然后是三分查找算法,时间复杂度O(3log3(n)):

       static bool Find(int[] sortedArray, int number)
        {
            if (sortedArray.Length == 0)
                return false;

            int start = 0;
            int end = sortedArray.Length - 1;

            while (end >= start)
            {
                int firstMiddle = (end - start) / 3 + start;
                int secondMiddle = end - (end - start) / 3;
                if (sortedArray[firstMiddle] > number)
                    end = firstMiddle - 1;
                else if (sortedArray[secondMiddle] < number)
                    start = secondMiddle + 1;
                else if (sortedArray[firstMiddle] != number && sortedArray[secondMiddle] != number)
                {
                    end = secondMiddle - 1;
                    start = firstMiddle + 1;
                }
                else
                    return true;
            }
            return false;
        }

由此可见,三分算法的时间复杂度比二分算法的要高,所以可以节省一定的时间,但是实际效率却要低,算法实现也更加复杂。

三分查找和二分查找结合求解目标值:

double sanfen(double l,double r)//三分查找
{
    double mid,midmid;
    while((r-l)>1e-9)//这里注意精度,1e-8就WA了
    {
        mid=(l+r)/2;
        midmid=(mid+r)/2;
        if(f(mid)>f(midmid))
            r=midmid;
        else
            l=mid;
    }
    return (mid+midmid)/2;
}

double erfen(double l,double r)//二分查找
{
    double mid;
    while((r-l)>1e-9)
    {
        mid=(l+r)/2;
        if(f(mid)>y)
            r=mid;
        else
            l=mid;
    }
    return mid;
}

你可能感兴趣的:(二分和三分)