二分算法--的几点思考

来源:互联网 发布:es6 对象数组去重 编辑:程序博客网 时间:2024/05/29 03:19

之前写的二分算法的模板  现在略作更新

点击打开链接

标准的二分算法的形式是:

template<class Typep>int BinarySearch(Type a[],const Type& x,int n) // 总共n个值 数组从0开始 {     int left=0;     int right=n-1;     while(left<=right){          int middle=(left+right)/2;          if(a[middle]==x)return middle;  //返回查找到的位置           if(a[middle]>x)right=middle-1;          else left=middle+1;                       }          return -1;  //没有找到      }

但是往往题中给出的不是数组中的数,需要在数组中找到比查找的值刚刚大的数,那么我们就需要改动return -1;的值 那么改到什么最好呢?

下面我们就来证明

a[1]   a[2]    a[3]

10    20      30

a[1]=10;  a[2]=20;  a[3]=30;

现在我们要查找15;

(1)查找的范围值[1,2]  ------这里指的是数组的位置

left=1,right=2;

进入while 循环中 

middle=1;

num>a[middle]=a[1];

left=middle+1;

result:      left=2;  midddle=1,right=1;

跳出循环

(2)  查找的范围是[1,3]

left=1,right=3;

进入while循环

middle=2;

num<a[middle]=a[2]

right=middle-1=1;

middle=2,left=1;

进行第二次循环

middle=1;

a[middle]<num

left=middle+1=2;

left=2; middle=1,right=1;

因为是二分查找的情况 所有的情况都会演变成[1,2]和[1,,3]的情况

然后如果要找刚刚大于一点的 选择left的

若是要找刚刚小于一点的 选择right

----  上面的这两句话就是更改最后一个return 的值 是他返回left和right

然后要注意的是  可以再所给集合中多添加两个边界值 使之 将所有的范围固定 这样就可以求解了

举个例子

要对下面的8个数进行2分查找

2,55,6,7,35,34,88,56

我们加上两个边界值 -1000和1000 控制范围

#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;int a[10]={-1000,1000,2,55,6,7,35,34,88,56};int BinarySearch(int n,int num){     int left=0;     int right=n-1;     int middle;     while(left<=right){      //printf("left=%d right=%d\n",left,right);        middle=(left+right)/2;        if(a[middle]==num)return middle;        if(a[middle]>num)right=middle-1;        else left=middle+1;                        }                 return left;   //刚刚大于一点的}int main(){   sort(a,a+10);   int n=10;         //8个查找数加上两个范围   int num;   for(int i=0;i<10;i++)      printf("%d ",a[i]);   printf("\n");    while(scanf("%d",&num)!=EOF){        int pos=BinarySearch(n,num);        printf("pos=%d a[%d]=%d\n",pos,pos,a[pos]);   }  }














原创粉丝点击