黄金分割查找

来源:互联网 发布:罗马安全吗 知乎 编辑:程序博客网 时间:2024/06/10 02:58

在二分查找中,我们是取mid等于left和right的中间值,即用等分的方法进行查找。
那为什么一定要等分呐?能不能进行“黄金分割”?也就是mid=left+0.618(right-left),当然mid要取整数。如果这样查找,时间复杂性是多少?也许你还可以编程做个试验,比较一下二分法和“黄金分割”法的执行效率。
(本例用C语言中的CLOCK来测定程序时间)

#include <stdio.h>#include <stdlib.h>#include <time.h>#define MAXLength 10000000struct Node {    int Element[MAXLength];    int Length;};typedef struct Node *List;clock_t start1, stop1, start2, stop2;double duration;int BinarySearch (List Tbl, int K);int GoldenSearch (List Tbl, int K);int main(){    int i, j, result;    List Tbl = (List) malloc(sizeof(struct Node));    Tbl->Length = MAXLength-1;    for (i=0;i<MAXLength;i++){        Tbl->Element[i] = i;    }    start1 = clock();    for (j=1;j<=MAXLength-1;j++){        result = BinarySearch (Tbl, j);    }    stop1 = clock ();    duration = ((double)(stop1-start1))/CLK_TCK/(MAXLength-1);    printf ("Duration of BinarySearch is %6.2es.\n", duration);     start2 = clock();    for (j=1;j<=MAXLength-1;j++){        result = GoldenSearch (Tbl, j);    }    stop2 = clock ();    duration = ((double)(stop2-start2))/CLK_TCK/(MAXLength-1);    printf ("Duration of GoldenSearch is %6.2es.\n", duration);     return 0;}int GoldenSearch (List Tbl, int K){    int left, right, mid, NoFound = -1;    left = 1;    right = Tbl->Length;    while (left<=right){        mid=left+0.618*(right-left);        if(K<Tbl->Element[mid]) right = mid-1;        else if (K>Tbl->Element[mid]) left = mid+1;        else return mid;    }     return NoFound;    }int BinarySearch (List Tbl, int K){    int left, right, mid, NoFound = -1;    left = 1;    right = Tbl->Length;    while (left<=right){        mid = (left+right)/2;        if(K<Tbl->Element[mid]) right = mid-1;        else if (K>Tbl->Element[mid]) left = mid+1;        else return mid;    }     return NoFound;}

算了下在一个长度为MAXLength、a[i]等于i的数组里面,找一个i平均要花的时间。让MAXLength等于10000000。
输出:
Duration of BinarySearch is 1.35e-007s.
Duration of GoldenSearch is 2.74e-007s.

二分法每次能有100%的概率能只剩50%的数据,每次剩下的期望为50%,即每次除以2。所以时间复杂度是。
而黄金分割的话每次都有0.618的概率剩0.618,0.382的概率剩0.382,每次剩下的期望为0.528,即每次除以1.894。所以时间复杂度是。

虽然两者都是O(logN)类,但是系数不同,黄金分割法所需时间约为二分法的1.085倍(此处没考虑取整……)。

假设分割点距左侧的距离除以全长等于p,那么每次剩下的期望为个全长。要让这个期望最小,我们知道p要等于1-p。所以p=0.5。所以二分法分在正中。

1 0