二分查找算法

一、主要步骤:

1.对数组等进行排序,保证查找的序列是有序的
2.进行二分查找

1.二分概念:

二分算法又称折半查找,即在一个单调有序的集合中查找一个解。每次分为左右两部分,判断解在哪个部分中并调整上下界,直到找到目标元素,每次二分后都将舍弃一半的查找空间。

2.算法复杂度

O(logn)

3.二分法常见模型

(1)二分查找

在一个单调有序的区间上求解分界点。

(2)二分答案

最小值最大(最大值最小)问题,这类双最值问题常常选用二分法求解,也就是确定答案后,配合贪心、DP等其他算法检验这个答案是否合理,将最优化问题转换为判定性问题。
注:一般题目默认在一个从小到大的区间上。

二、为什么要用二分:

二分查找法,又称折半查找法。但该方法是建立在有序的前提下的,基本思路就是:先找到那个有序序列的中间元素mid,然后拿它和要找的元素K进行比较,就可以初步判断K所在范围,既然查找范围已确定,自然该范围之外的元素就可以不用再查找了(你看这样相较于顺序查找一下子就可以省略一半的元素不用查找了,这就是效率啊!!!)。当然接下来还会按照上面的步骤反复查找下去。

二分的时间复杂度是O(logn),比直接查找要快。

三、模板代码:

1.查找数组中是否存在n

#include<bits/stdc++.h>//万能头
using namespace std;
/*找是否存在数n*/
int a[10]={0,1,2,3,4,5,6,7,8,9};
int main(){
	int n;
	cin>>n;
	int left=0,right=9,mid;
	while (left <= right){
		mid = (left + right) >>1;//计算中间元素的下标
		if (a[mid] < n) left = mid + 1;
		else if (a[mid] > n) right = mid - 1;
		else break;
	}
	if (left > right)	printf("没有找到该数\n");
	else printf("找到了\n");
	return 0;
}

2.查找n在数组中的范围

/*找n在数组中的范围(下标)*/
while(left<right-1){
	mid=(left+right)>>1;
	if(n>=a[mid])
		left=mid;
	else right=mid;
}
cout<<left<<" "<<right;

四、二分函数

1.binary_search()——利用二分方法判断一个数是否被找到

vector<int> a { 1,1,2,2,3,3 };
    int aa=binary_search(a.begin(),a.end(),10);//bool 
    cout<<aa;//1能被找到,0不能被找到

2.lower_bound()——返回第一个大于等于搜索数的位置,要减去地址

3.upper_bound()——返回第一个大于搜索数的位置,要减去地址

vector<int> a { 1,1,2,2,3,3 };//对于一个已经排好序的数组
//插入一个数,那么应该在哪个位置
    int aa=lower_bound( a.begin(),a.end(),3 )-a.begin();
    int bb=upper_bound()(a.begin(),a.end(),3)-a.begin();
    cout<<aa<<" "<<bb;
    /*返回指针即下标
    第一个位置是下标为aa的位置
    最后一个位置是下标为bb的位置*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值