STL二分查找和手写二分

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
数组中是否存在191
第一个大于等于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
数组中是否存在1000
第一个大于等于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;//返回下标
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值