各种二分查找
来源:互联网 发布:淘宝付款后,微信立返 编辑:程序博客网 时间:2024/05/16 04:45
二分查找
给定一个有序(不降序)数组arr。
1、求任意一个i使得arr[i]等于val,不存在则返回-1
2、求最小的i使得arr[i]等于val,不存在则返回-1
3、求最大的i使得arr[i]等于val,不存在则返回-1
4、求最大的i使得arr[i]小于val,不存在则返回-1
5、求最小的i使得arr[i]大于val,不存在则返回-1
一个错误的二分查找:
- int bisearch(int *arr, int b, int e, int val)
- {
- while(b<e)
- {
- int mid = (b+e)>>2;
- if(arr[mid] <= val)
- {
- b = mid;
- }
- else
- {
- e = mid-1;
- }
- }
- if(arr[e] == val)
- {
- return e;
- }
- else
- {
- return -1;
- }
- }
下面通过构建测试用例来找出这个程序的问题
对于所有有效输入
在arr数组中查找元素val,对于问题123构建如下的测试用例。
arr数组
找到
未找到
空集
不存在
1
1个元素
2
3
多个元素
arr中含有一个val 含有多个
位于arr开头 4 5
结尾 6 7
中间 8 9
比最小的小 10
比最大的大 11
在范围内就是不含有 12
构建测试用例
1
int a1[] = {};
cout << bisearch(a, 0, sizeof(a1)/sizeof(int)-1, 8) << endl;
2
int a2[] = {8};
cout << bisearch(a, 0, sizeof(a2)/sizeof(int)-1, 8) << endl;
3
int a3[] = {10};
cout << bisearch(a, 0, sizeof(a3)/sizeof(int)-1, 8) << endl;
4
int a4[] = {1,2,3,4,5,6,7,7,7,7,7};
cout << bisearch(a, 0, sizeof(a4)/sizeof(int)-1, 1) << endl;
5
int a5[] = {1,1,1,2,3,4,5,6,7,7,7,7,7};
cout << bisearch(a, 0, sizeof(a5)/sizeof(int)-1, 1) << endl;
6
int a6[] = {1,2,3,4,5,6,7,7,7,7,7,8};
cout << bisearch(a, 0, sizeof(a6)/sizeof(int)-1, 8) << endl;
7
int a7[] = {1,2,3,4,5,6,7,7,7,7,7,8,8,8,8};
cout << bisearch(a, 0, sizeof(a7)/sizeof(int)-1, 8) << endl;
8
int a8[] = {1,2,3,4,5,6,7,7,7,7,7,8,8,8,10,10,12};
cout << bisearch(a, 0, sizeof(a8)/sizeof(int)-1, 6) << endl;
9
int a9[] = {1,2,3,4,5,6,7,7,7,7,7,8,8,8,10,10,12};
cout << bisearch(a, 0, sizeof(a9)/sizeof(int)-1, 8) << endl;
10
int a10[] = {2,3,4,5,6,7,7,7,7,7};
cout << bisearch(a, 0, sizeof(a10)/sizeof(int)-1, 1) << endl;
11
int a11[] = {2,3,4,5,6,7,7,7,7,7};
cout << bisearch(a, 0, sizeof(a11)/sizeof(int)-1, 12) << endl;
12
int a12[] = {2,3,4,5,7,7,7,7,7};
cout << bisearch(a, 0, sizeof(a12)/sizeof(int)-1, 6) << endl;
期望的测试结果
测试用例编号
问题1
问题2
问题3
1
-1
-1
-1
2
0
0
0
3
-1
-1
-1
4
0
0
0
5
0-2任意
0
2
6
11
11
11
7
11-14任意
11
14
8
5
5
5
9
11-13
11
13
10
-1
-1
-1
11
-1
-1
-1
12
-1
-1
-1
对于上面那个错误程序:测试样例4进入死循环,经过分析发现,(来自编程之美)
也就是说一种情况下没有缩小范围导致。
对每一种情况都缩小范围,可以得到题目1的如下代码:可以通过全部测试样例
- //递归
- int bisearch(int *arr, int s, int e, int val)
- {
- if(s>e) return -1;
- int mid = s + ((e - s) >>1);
- if(arr[mid] == val) return mid;
- else if(arr[mid] < val) return bisearch(arr,mid+1, e, val);
- else return bisearch(arr,s, mid-1, val);
- }
- // 非递归
- int bisearch(int *arr, int s, int e, int val)
- {
- while(s<=e)
- {
- int mid = s + ((e-s)>>2);
- if(arr[mid]==val) return mid;
- else if(arr[mid]<val) s=mid+1;
- else e=mid-1;
- }
- return -1;
- }
- //或者
- int bisearch(int *arr, int s, int e, int val)
- {
- /*
- 循环结束有两种情况
- s为偶数 s=e
- s为奇数 s=e-1
- */
- while(s < e-1)
- {
- int mid = s+((e-s)>>1);
- if(arr[mid]<=val)
- {
- s=mid;
- }else{
- // 不需要e=mid-1 防止s=e
- e=mid;
- }
- }
- if(arr[s]==val) return s;
- if(arr[e]==val) return e;
- return -1;
- }
- //第二题:
- int bisearch(int *arr, int s, int e, int val)
- {
- while(s <= e)
- {
- if(arr[s]==val) return s;
- int mid = s+((e-s)>>1);
- if(arr[mid]<val)
- {
- s=mid+1;
- }else if(arr[mid]==val){
- e=mid;
- } else{
- e=mid-1;
- }
- }
- return -1;
- }
- //第三题:
- int bisearch(int *arr, int s, int e, int val)
- {
- while(s <= e)
- {
- if(arr[e]==val) return e;
- int mid=s+((e-s-1)>>2)+1; // 尽量往后落,也就是3和4落在4 2和6仍然也落在4
- if(arr[mid] < val)
- s=mid+1;
- else if(arr[mid] == val)
- s=mid;
- else
- e=mid-1;
- }
- return -1;
- }
对于4,5问题不存在找不到的情况,构建测试用例
arr
val
空集
任意1
1个
相等2
大于3
小于 4
多个
小于最小5
等于最小 6
在中间相等7 不等8
等于最大 9
大于最大10
1
int a1[] = {};
cout << bisearch(a1, 0, sizeof(a1)/sizeof(int)-1, 8) << endl;
2
int a2[] = {8};
cout << bisearch(a2, 0, sizeof(a2)/sizeof(int)-1, 8) << endl;
3
int a3[] = {10};
cout << bisearch(a3, 0, sizeof(a3)/sizeof(int)-1, 8) << endl;
4
int a4[] = {5};
cout << bisearch(a4, 0, sizeof(a4)/sizeof(int)-1, 8) << endl;
5
int a5[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a5, 0, sizeof(a5)/sizeof(int)-1, 1) << endl;
6
int a6[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a6, 0, sizeof(a6)/sizeof(int)-1, 3) << endl;
7
int a7[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a7, 0, sizeof(a7)/sizeof(int)-1, 7) << endl;
8
int a8[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a8, 0, sizeof(a8)/sizeof(int)-1, 9) << endl;
9
int a9[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a9, 0, sizeof(a9)/sizeof(int)-1, 18) << endl;
10
int a10[] = {3,5,6,7,7,7,8,8,8,8,12,18};
cout << bisearch(a10, 0, sizeof(a10)/sizeof(int)-1, 20) << endl;
测试用例编号
问题4
问题5
1
-1
-1
2
-1
-1
3
-1
0
4
0
-1
5
-1
0
6
-1
1
7
2
6
8
9
10
9
10
-1
10
11
-1
- //第四题
- int bisearch(int *arr, int s, int e, int val)
- {
- //求最大的i使得arr[i]小于val,不存在则返回-1
- while(s<=e){
- if(arr[e]<val) return e;
- int mid = s+((e-s-1)>>1)+1;
- if(arr[mid]<val){
- s=mid;
- }
- else{
- e=mid-1;
- }
- }
- return -1;
- }
- //第五题
- int bisearch(int *arr, int s, int e, int val)
- {
- //求最小的i使得arr[i]大于val,不存在则返回-1
- while(s<=e){
- if(arr[s] > val) return s;
- int mid = s + ((e-s)>>1);
- if(arr[mid]<=val){
- s=mid+1;
- } else{
- e=mid;
- }
- }
- return -1;
- }
原文地址:点击打开链接
- 各种二分查找
- 各种二分查找
- 二分查找的各种条件
- 二分查找及各种变化
- 各种二分查找算法总结
- python之各种二分查找
- 二分查找各种情况汇总
- 算法 之二分查找的各种版本
- 二分查找各种情况大总结
- 二分查找各种情况大总结
- 二分查找各种情况大总结
- [置顶] 二分查找各种情况大总结
- 各种查找算法-Java-顺序、二分、二叉排序树查找
- 二分查找的各种情况实现以及一些注意点
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- java db
- 开发系统的一点小看法
- Android应用程序消息处理机制(Looper、Handler)分析
- 编程之美系列之求子数组的最大乘积
- 【shell】sh: 0: getcwd() failed: No such file or directory
- 各种二分查找
- 超棒的CSS开源UI界面元素类库 - TopCat
- C# 多线程 异步回调
- 希尔排序
- 中断处理之RTC
- SQL有外连接的时候注意过滤条件位置
- baitxttgchx天工网bs
- 正式加入csdn
- Android ActionBar 一步一步分析