STL二分查找:
头文件:
#include< algorithm >
适用对象:
单调非减序列。
简介:
1、binary_search:查找某个元素是否出现,返回true/false
形式:binary_search(begin,end,num)
功能:在数组的[begin,end)区间进行二分查找,找到num元素则返回真,否则返回假。
2、lower_bound:返回第一个大于或等于某个元素的数的地址。
形式:lower_bound(begin,end,num):
功能:在数组的[begin,end)区间进行二分查找,返回第一个大于或等于num的元素的地址。如果所有元素都小于num,则返回end的地址。
3、upper_bound:返回第一个大于某个元素的数的地址。
形式:upper_bound(begin,end,num):
功能:在数组的[begin,end)区间进行二分查找,返回第一个大于num的元素的地址。如果所有元素都小于num,则返回end的地址。
注: lower_bound和upper_bound返回的是(int *)地址,所以为了获得元素下标,还需减去首地址。
演示:
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
const int maxn=1e4+5;
const int N=20;
int a[maxn];
int main()
{
srand(time(NULL));//置随机数种子
for(int i=0;i<N;i++)//产生N个[0,100)的随机数
a[i]=rand()%100;
sort(a,a+N);//排序,二分查找要求单调非减
for(int i=0;i<N;i++)//输出排序后的数
{
if(i<N-1)
printf("%d ",a[i]);
else
printf("%d\n",a[i]);
}
int num;
printf("请输入要查找的数:");
scanf("%d",&num);
int ans1=binary_search(a,a+N,num);//返回true/false
int ans2=lower_bound(a,a+N,num)-a;//lower_bound返回的是地址,减去首地址才能得到所在下标
int ans3=upper_bound(a,a+N,num)-a;//upper_bound返回的是地址,减去首地址才能得到所在下标
int ans4=ans3-ans2;//大于下标 - 大于等于下标 = 等于的个数
printf("数组中是否存在%d:%d\n",num,ans1);
printf("第一个大于等于%d的数所在下标:%d\n",num,ans2);
printf("第一个大于%d的数所在下标:%d\n",num,ans3);
printf("数组中%d的个数:%d\n",num,ans4);
return 0;
}
测试:
第一组:
0 5 6 9 15 19 19 29 38 45 48 53 58 62 69 84 92 92 95 99
请输入要查找的数:19
数组中是否存在19:1
第一个大于等于19的数所在下标:5
第一个大于19的数所在下标:7
数组中19的个数:2
第二组:
1 18 20 21 24 26 31 38 41 43 56 65 71 79 81 82 85 94 98 99
请输入要查找的数:100
数组中是否存在100:0
第一个大于等于100的数所在下标:20
第一个大于100的数所在下标:20
数组中100的个数:0
手写二分:
bool binarySearch(int arr[],int left,int right,int num)
{
int l=left,r=right-1,mid;
while(l<=r)
{
mid=(l+r)>>1;//为避免l+r溢出可写成 l+((r-l)>>1), +的优先级比>>高
if(arr[mid]==num)
return true;
if(arr[mid]<num);
l=mid+1;
if(arr[mid]>num)
r=mid-1;
}
return false;
}
int lowerBound(int arr[],int left,int right,int num)//大于等于
{
int l=left,r=right-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(arr[mid]<num)
l=mid+1;
else
r=mid-1;
}
return l;//返回下标
}
int upperBound(int arr[],int left,int right,int num)//大于
{
int l=left,r=right-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(arr[mid]<=num)
l=mid+1;
else
r=mid-1;
}
return l;//返回下标
}