【第四周】算法之二分算法

1.引言

问题:A心里想一个1-1000之间的数,B来猜,可以问问题,A只能回答是或否。怎么猜才能问的问题最少?

  • 是1吗?是2吗?…是999吗?这样猜平均要问500次
  • 大于500吗?大于750吗?大于625吗?…每次缩小猜测范围到上次的一半,只需要10次

这样就得出了我们的二分算法,二分算法就是每次缩小一半的范围来确定查找的数值,这样会节省查找时间,优化算法。
二分算法有一个条件就是在查找区间内需要保证数据有序排列

2. 二分查找函数

  • 写一个函数BinarySerch,在包含size个元素的、从小到大排序的int数组a里查找元素p,如果找到,则返回元素下标,如果找不到,则返回-1,要求复杂度o(log(n))
int BinarySearch(int a[],int size,int p)
{
	int L;//查找区间的左端点,用下标表示
	int R=size-1;//查找区间的右端点
	while(L<=R){//如果查找区间不为空就继续查找 
		int mid=L+(R-L)/2;//这里为了防止(R+L)/2 溢出 取查找区间正中元素的下标 
		if(a[mid]==p){
			return mid;
		}
		else if(a[mid]>p){
			R=mid-1;//设置新的查找区间的右端点 
		}
	    else if(a[mid]<P){
			R=mid+1;//设置新的查找区间的左端点 
		}
	  return -1;//没有找到,返回-1 
	} 
}
  • 写一个函数LowerBound,在包含size个元素的、从小到大排序的int数组a里查找比给定整数p小的,下标最大的元素。找到则返回其下标,找不到返回-1
int LowerBound(int a[],int size,int p)
{
	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;
}

3.例题

例题一:找一对数

题目描述:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了70 篇原创文章 · 获赞 36 · 访问量 8661

猜你喜欢

转载自blog.csdn.net/qq_44867340/article/details/105151224