编程之美3.11 二分查找

编程之美3.11

看了编程之美3.11才发现原来写一个正确完整的二分查找是如此困难,尤其是对边界条件的考察,不同的二分查找要对特殊用例进行测试,才能写出正确的代码。

#include<iostream>
using namespace std;
/*1.给定一个有序(不降序)数组a[],求任意一个i使得a[i]等于value,不存在则返回-1*/
int BinarySearchEqual(int* a,int low ,int high,int value)
{
if(a==NULL)return -1;
int mid;
while(low<=high)
{
mid=low+(high-low)/2;
if(a[mid]<value)
low=mid+1;
else
if(a[mid]>value)
high=mid-1;
else
return mid;
}
return -1;
}


/*2.给定一个有序(不降序)数组a[],求最小的i使得a[i]等于value,不存在则返回-1*/

/*若查找的数组中全等于要查找的数,high会越界,2和4中没有讨论value值等于mid值,若加入一个这样的讨论,然后判断mid前面的值,就可以知道这样的mid值是否首次出现,使得算法的思路更加清晰。又因为数组中不能明确表明存在这样的value值,所以边界检测是必要的,若存在,可以直接return low,返回一个大于等于value的值*/

int BinarySearchFirstEqual(int *a,int low,int high,int value)
{
if(a==NULL)return -1;
int mid;
while(low<=high)
{
mid=low+(high-low)/2;
if(a[mid]<value)
low=mid+1;
else
high=mid-1;
}
if(a[low]==value)return low;
return -1;
}


/*3.给定一个有序(不降序)数组a[],求最大的i使得a[i]等于value,不存在则返回-1*/

/*若查找的数组中全等于要查找的数,low会越界,3和5中没有讨论value值等于mid值,若加入一个这样的讨论,然后判断mid后面的值,就可以知道这样的mid值是最后出现,使得算法的思路更加清晰。又因为数组中不能明确表明存在这样的value值,所以边界检测是必要的,若存在,可以直接return high,返回一个小于等于value的值*/

int BinarySearchLastEqual(int*a,int low ,int high, int value)
{
if(a==NULL)return -1;
int mid;
while(low<=high)
{
mid=low+(high-low)/2;
if(a[mid]<=value)
low=mid+1;
else high=mid-1;
}
if(a[high]==value)return high;
return -1;
}


/*4.给定一个有序(不降序)数组a[],求最大的i使得a[i]小于value,不存在则返回-1*/
/*此查找等同于2,利用2的特例时high会越界,保存初始low,进行判断high是否越界*/

int BinarySearchLess(int*a,int low,int high,int value)
{
if(a==NULL)return -1;
int mid;
int temp=low;
while(low<=high)
{
mid =low+(high-low)/2;
if(a[mid]<value)low=mid+1;
else high=mid-1;
}
if(high<temp||a[high]>=value)return -1;
else return high;
}


/*5.给定一个有序(不降序)数组a[],求最小的i使得a[i]大于value,不存在则返回-1*/

/*此查找等同于3,利用3的特例时low会越界,保存初始high,进行判断low是否越界*/

int BinarySearchGreater(int*a,int low,int high,int value)
{
if(a==NULL)return -1;
int mid;
int temp=high;
while(low<=high)
{
mid =low+(high-low)/2;
if(a[mid]<=value)low=mid+1;
else high=mid-1;
}
if(low>temp||a[low]<=value)return -1;
else return low;
}

测试:
int main()
{
int a[]={2,4,5,10,20,33,89};
int b[]={1,1,1,1,1,1,1,2,5,5,9,9,9,9,9};
cout<<"Equal:"<<endl;
cout<<BinarySearchEqual(a,0,6,2)<<endl;
cout<<BinarySearchEqual(a,0,6,89)<<endl;
cout<<BinarySearchEqual(a,0,6,10)<<endl;
cout<<endl;
cout<<"First Equal:"<<endl;
cout<<BinarySearchFirstEqual(b,0,14,1)<<endl;
cout<<BinarySearchFirstEqual(b,0,14,5)<<endl;
cout<<BinarySearchFirstEqual(b,0,14,9)<<endl;
cout<<endl;
cout<<"Last Equal:"<<endl;
cout<<BinarySearchLastEqual(b,0,14,1)<<endl;
cout<<BinarySearchLastEqual(b,0,14,5)<<endl;
cout<<BinarySearchLastEqual(b,0,14,9)<<endl;
cout<<endl;
cout<<"Last Less:"<<endl;
cout<<BinarySearchLess(a,0,6,1)<<endl;
cout<<BinarySearchLess(a,0,6,90)<<endl;
cout<<BinarySearchLess(b,0,14,1)<<endl;
cout<<endl;
cout<<"First Greater:"<<endl;
cout<<BinarySearchGreater(a,0,6,90)<<endl;
cout<<BinarySearchGreater(a,0,6,1)<<endl;
cout<<BinarySearchGreater(b,0,14,8)<<endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值