(一)在包含size个元素的、从小到大排序的int数组a里查找元素p,如果找到,则返回元素下标,如果找不到,则返回-1。
#include<iostream>
#include<cstdio>
using namespace std;
int BinarySearch(int a[],int p,int size);
int main(){
int a[100],p,size;
scanf("%d %d",&p,&size);
for(int i=0;i<size;i++){
scanf("%d",&a[i]);
}
printf("%d",BinarySearch(a,size,p));
return 0;
}
int BinarySearch(int a[],int p,int size){
int L=0;
int R=size-1;
while(L<=R){
int mid=L+(R-L)/2;
if(p==a[mid])
return mid;
else if(p>a[mid])
L=mid+1;
else
R=mid-1;
}
return -1;
}
理解:
数值 1 4 8 10 15
下标 0 1 2 3 4
要找的数 5
首先,这是一个有序序列,(0+4)/2=2,a[2]=8,5<8,继续向左半部分查找 (0+2)/2=1,a[1]=4,确定要找的数在下标1和2之间,但不存在5,查找失败。
(二)写一个函数LowerBound,在包含size个元素的、从小到大排序的int数组a里查找比给定整数p小的,下标最大的元素。找到则返回其下标,找不到则返回-1
#include<iostream>
#include<cstdio>
using namespace std;
int LowerBound(int a[],int p,int size);
int main(){
int a[100],p,size;
scanf("%d %d",&p,&size);
for(int i=0;i<size;i++){
scanf("%d",&a[i]);
}
printf("%d",LowerBound(a,p,size));
return 0;
}
int LowerBound(int a[],int p,int size){
int L=0;
int R=size-1;
int Lastpos=-1;
while(L<=R){
int mid=L+(R-L)/2;
if(a[mid]>=p)
R=mid-1;
else
Lastpos=mid;
L=mid+1;
}
return Lastpos;
}
理解:就是用二分的思想无限逼近要找的数,直到找到的数与要找的数的差最小。
(三)折半查找
void binarySearch(int *arr,int length,int key) {
int left = 0;
int right = length - 1;
int mid;
//在左右指针交换之前,查找还没结束
while (left <= right) {
//更新中间的值
mid = (left + right) / 2;
//查找成功
if (arr[mid] == key) {
cout << "find it and its index is " << mid;
return;
}
//若还没有找到,改变左右区间继续寻找
if (arr[mid] < key)
left = mid + 1;
if (arr[mid] > key)
right = mid - 1;
}
cout << "cannot find it" << endl;
return;
}
思考:折半查找会牵涉到low和high的交换