题目:
设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
回顾:
我们先来用C/C++来实现二分法:
(具体步骤讲解都在代码中的注释,所以我就不多讲了)
先用递归法熟悉一下:
#include<iostream> using namespace std; int BinarySearch(int arr[],int L,int R,int p) //arr数组,size数组长度,需要找的p { if(L>=R) { while(L <= R) //大条件就是L要不大于R { int mid = L + (R - L)/2; //区间中值 if(p == arr[mid]) //判断是否符合 return mid+1; //返回 else if(p > arr[mid]) //进一步判断p是满足mid的左边还是右边 return BinarySearch(arr,mid,R,p); //设置新的查找区间的左端点 else return BinarySearch(arr,R,mid,p); //设置新的查找区间的右端点 } } else return -1; } int main() { int arr[100],n,m; puts("请设置你要出入的元素个数:"); cin>>n; puts("请输入你要输入的各个元素:"); for(int i = 0;i < n;i ++) cin>>arr[i]; puts("请输入你要查找的元素:"); cin>>m; puts("对应位置为:"); cout<<BinarySearch(arr,0,n,m)<<endl; return 0; }
再用for循环来遍历二分查找:
#include<iostream> using namespace std; int BinarySearch(int arr[],int size,int p) //arr数组,size数组长度,需要找的p { int L = 0; //左区间 int R = size - 1; //右区间 while(L <= R) //大条件就是L要不大于R { int mid = L + (R - L)/2; //区间中值 if(p == arr[mid]) //判断是否符合 return mid+1; //返回 else if(p > arr[mid]) //进一步判断p是满足mid的左边还是右边 L = mid + 1; //设置新的查找区间的左端点 else R = mid - 1; //设置新的查找区间的右端点 } return -1; //未找到 } int main() { int arr[100],n,m; puts("请设置你要出入的元素个数:"); cin>>n; puts("请输入你要输入的各个元素:"); for(int i = 0;i < n;i ++) cin>>arr[i]; puts("请输入你要查找的元素:"); cin>>m; puts("对应位置为:"); cout<<BinarySearch(arr,n,m)<<endl; return 0; }
注意事项:
二分法道理很简单都是平时写的时候,容易忽略区间边界的问题导致运行出错;
例如int mid = L + (R - L)/2;我们要注意这些细节性问题;
(懂上面写的二分法之后,再来看下面改进过后用Java来实现的二分搜索算法)
示例代码:
import java.util.Scanner; class Search{ public static void main(String[] args) { int[] arr = {1,2,3,4,5,6,7}; Scanner in = new Scanner(System.in); int s = in.nextInt(); in.close(); int mid = BinarySearch(arr,s); if(mid >= 0)//判断搜索过后是否返回-1,若是,则结束,若不是,则打印s在数组中的下标位置; System.out.println(s+"所在数组中的下标为:"+mid); } public static int BinarySearch(int[] arr,int s) { int L = 0; //左区间 int R = arr.length-1; //右区间 int mid,i = 0,j = 0; while(L arr[mid]) L = mid + 1; else R = mid - 1; } /*当s不在数组中我们可以分成两种情况:1、s大于数组最大值;2、s小于数组最大值;*/ if(s > arr[arr.length-1]) System.out.println("数组中小于"+s+"的最大元素下标:"+i); else if(s < arr[arr.length-1]) System.out.println("数组中大于"+s+"的最小元素下标:"+j); else { System.out.println("数组中小于"+s+"的最大元素下标:"+i); System.out.println("数组中大于"+s+"的最小元素下标:"+j); } return -1;//在数组中未搜索到则返回-1 } }
代码仅供参考,看懂思路自己琢磨自己敲,只有在通过练习中领悟和体会其中的抽象,之后遇见什么问题都是迎刃而生的思考;
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复