二分哪些事儿

二分作为一种方法,或者说是一种思想,是很常用的,也是很好用的,所以介于我的二分能里比较弱,今天我就来总结整理一些知识,供大家分享。

说明:本文章参考于——http://blog.youkuaiyun.com/sunmenggmail/article/details/7540970

一.可能出现的一些问题

1.边界错误造成的问题

二分查找算法的边界,一般来说分两种情况,一种是左闭右开区间,类似于[left, right),一种是左闭右闭区间,类似于[left, right].需要注意的是, 循环体外的初始化条件,与循环体内的迭代步骤, 都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此.如果两者不一致,会造成程序的错误。如果两者同时都写错的话,可能会造成死循环。

2.溢出

假如,left与right之和超过了所在类型的表示范围的话,那么middle就不会得到正确的值.

二.代码实现

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[10];
int lowserach(int b[],int x,int y,int v)//注意求比其小的一项应减 1 
{
	int m;
	while(x<y)
	{
		m=x+(y-x)/2;
		if(b[m]>=v)y=m;
		else x=m+1;
	}
	return x;
}
int upserach(int b[],int x,int y,int v)
{
	int m;
	while(x<y)
	{
		m=x+(y-x)/2;
		if(b[m]<=v)x=m+1;
		else y=m; 
	}
	return x;
}
int findserach(int b[],int x,int y,int v)
{
	int m;
	while(x<=y)
	{
		m=x+(y-x)/2;
		if(b[m]==v)return m;
		else if(b[m]>v)y=m-1;
			 else x=m+1;	 
	}
}

int Bi_Search(int a[],int n,int b)//返回等于b的第一个
{
	if(n==0)
		return -1;
	int low = 0;
	int high = n-1;
	int last = -1;//用last记录上一次满足条件的下标
	while (low<=high)
	{
		int mid = low +(high-low)/2;
		if (a[mid]==b)
		{
			last = mid;
			high = mid -1;
		}
		else if(a[mid]>b)
			high = mid -1;
		else
			low = mid +1;
	}

	return last;


}
int Bi_Search1(int a[],int n,int b)//大于b的第一个数
{
	if(n<=0)
		return -1;
	int last = -1;
	int low = 0;
	int high = n-1;
	while (low<=high)
	{
		int mid = low +(high - low)/2;
		if(a[mid]>b)
		{
			last = mid;
			high = mid -1;
		}
		else if (a[mid]<=b)
		{
			low =mid +1;
		}
	}

	return last;
}
int Bi_Search2(int a[],int n,int b)//小于b的第一个数
{
	if(n<=0)
		return -1;
	int last = -1;
	int low = 0;
	int high = n-1;
	while (low<=high)
	{
		int mid = low +(high - low)/2;
		if(a[mid]<b)
		{
			low =mid +1;
			last = mid;
		}
		else if (a[mid]>=b)
		{
			high = mid -1;
		}
	}

	return last;
}

int main()
{
	freopen("1.txt","r",stdin);//1 3 5 5 5 8 8 9
	for(int i=1;i<=8;i++)
		cin>>a[i];
	int pos1,pos2;
	pos1=upper_bound(a+1,a+9,7)-a;
	pos2=lower_bound(a+1,a+9,7)-a;//注意求比其小的一项应减 1 
	cout<<pos1<<" "<<a[pos2]<<endl;
	cout<<upserach(a,1,8,7)<<" "<<a[lowserach(a,1,8,7)]<<" "<<endl;//<<
	cout<<Bi_Search1(a,8,7)<<" "<<a[Bi_Search2(a,8,7)]<<endl;
	cout<<Bi_Search(a,8,7)<<" "<<findserach(a,1,8,7);
	while(1);
	return 0;
}



当然我们也可以用algori
thm库中的二分函数:

        pos=upper_bound(a,a+n,pos)-a;
	pos=lower_bound(a,a+n,pos)-a;//注意求比其小的一项应减 1 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值