二分查找

来源:互联网 发布:生日祝福源码 编辑:程序博客网 时间:2024/06/14 05:23

       一下是一个正确的二分查找程序:

int search(int array[], int n, int v){    int left, right, middle;    left = 0, right = n - 1;    while (left <= right)    {        middle = (left + right) / 2;        if (array[middle] > v)        {            right = middle;        }        else if (array[middle] < v)        {            left = middle;        }        else        {            return middle;        }    }    return -1;}

        这个程序存在一些问题:

1、  这个查找程序只是找到存在元素的标号,但是元素的位置不定,也就是说如果序列中存在多个所查询的值,返回的并不一定是第一个或者是最后一个的后一个位置。

2、  运用middle=left+right/2可能导致溢出,所以更加安全的做法就是middle=left+right-left/2

          下面提供两个更合适的程序

1、  返回序列中第一个所查元素的标号。

int low_bound(int array[], int n, int v){    int left, right, middle;    left = 0, right = n - 1;    while (left != right)        {        middle=left+(right-left)/2;        if (array[middle] < v)            left = middle+1;            else              //因为当仅剩余两个元素的时候,middle=left            right = middle; //所以改变right可以跳出循环    }    if(array[left] == v)  //此时left(left=right)的标号就是元素应当插入的位置return left;  //如果将这里的判定删除,仅仅是返回leftelse  //的话那就是指元素应当被插入的位置。return -1;}

2、返回最后一个元素位置

int up_bound(int array[], int n, int v){    int left, right, middle;    left = 0, right = n - 1;    while (left != right)              {        middle=left+(right-left)/2;        if (array[middle] > v)            right = middle;        else             left = middle+1;       //用这种方式返回的是插入位置,所以接下来进行判定    }    //!!!!只有这样才可以跳出循环!!!!!    if(array[left-1] == v)          //一般要返回元素是否存在的程序,都不用up_boundreturn left-1;  else return -1;}

       测试程序:

int main(){int a[10]={1,1,6,6,6,6,7,7,7,9};//int index=search(a,10,6);//int index=low_bound(a,10,5);int index=up_bound(a,10,5);//int index=binary_search(a,10,6);printf("%d",index);return 0;}


 

 

原创粉丝点击