云淡风轻
Stay foolish,stay hungry.
1,给定一个有序(不降序)数组arr,求任意一个i使得arr[i]等于v,不存在则返回-1。
2,给定一个有序(不降序)数组arr,求最小的i使得arr[i]等于v,不存在则返回-1。
3,给定一个有序(不降序)数组arr,求最大的i使得arr[i]等于v,不存在则返回-1。
4,给定一个有序(不降序)数组arr,求最大的i使得arr[i]小于v,不存在则返回-1。
5,给定一个有序(不降序)数组arr,求最小i使得arr[i]大于v,不存在则返回-1。

解答:我们一个个来解决,第一个问题相对简单,但要注意边界条件,代码如下:
//二分查找在字符串数组arr中找到任意一个i,使得arr[i]=v,不存在则返回-1,
//1,递归版本
int BS(char **arr,char *v,int i,int j){
if(i>=j){
if(!strcmp(arr[i],v)){
return i;
}
else 
return -1;
}
int mid=i+(j-i)/2;    //注意不能写成mid=(i+j)/2,容易产生加法溢出
if(!strcmp(arr[mid],v))
return mid;
else if(strcmp(arr[mid],v)>0)
return BS(arr,v,i,mid-1);
else
return BS(arr,v,mid+1,j);
}
第二个问题,只要改变一下在与中间值相同的时候,状态转移函数发生变化
//二分查找在字符串数组arr中寻找最小的i,使得arr[i]=v,不存在则返回-1,
//递归版本
int BS_min(char **arr,char *v,int i,int j){
if(i>=j){
if(!strcmp(arr[j],v)){  //注意这里也有所不同
return j;
}
else 
return -1;
}
int mid=i+(j-i)/2;
if(!strcmp(arr[mid],v))//相等,继续在左边找,注意下标是mid而不是mid-1
return BS_min(arr,v,i,mid);
else if(strcmp(arr[mid],v)>0)
return BS_min(arr,v,i,mid-1);
else
return BS_min(arr,v,mid+1,j);
}
第三个问题和第二个问题类似:
//二分查找在字符串数组arr中寻找最大的i,使得arr[i]=v,不存在则返回-1,
//递归版本
int BS_max(char **arr,char *v,int i,int j){
if(i>=j || i==j-1){//如果不加i==j-1,程序可能会进入死循环
if(!strcmp(arr[j],v)){
return j;
}
else if(!strcmp(arr[i],v)){
return i;
}
else 
return -1;
}
int mid=i+(j-i)/2;
if(!strcmp(arr[mid],v))//相等,继续在右边找,注意下标是mid而不是mid+1
return BS_max(arr,v,mid,j);
else if(strcmp(arr[mid],v)>0)
return BS_max(arr,v,i,mid-1);
else
return BS_max(arr,v,mid+1,j);
}
第四题稍微有点难度
posted on 2011-12-21 22:41  kevin Lee  阅读(300)  评论(0编辑  收藏  举报