c++/c语言 二分法基础代码详解

代码解析如下:

以一个有序数列查找其中的数为例;二分查找能把 O ( n ) 的时间复杂度降到O(log n),大大减小了时间复杂度;

#include<bits/stdc++.h>
using namespace std;
//a[] 为严格递增序列,left为二分下界,right为二分上界,x为欲查询的数
//二分区域为左闭右闭的[left,right],传入的初值为[0,n-1]
int binarysearch(int a[],int left,int right,int x) {
	int mid;
	while(left<=right) { // 如果left>right 就没办法形成闭区间了
		mid=(left+right)/2;// 取中点
		if(a[mid]==x) return mid;//找到mid 返回下标
		else if(a[mid]>x) {//往左子区间[left,mid-1]查找 
			right=mid-1;
		} else {//中间的数小于x 
			left=mid+1;//往右子区间 [mid+1,right]查找。 
		}
	}
	return -1;//查找失败返回-1; 
}
int main() {
	const int n=10;
	int a[n]= {1,3,4,6,7,8,10,11,12,15};
	printf("%d %d",binarysearch(a,0,n-1,6),binarysearch(a,0,n-1,9));
	return 0;
}

如果有重复的数字,可以简单拓展一下如下。

找出重复数字第一次出现的位置:

#include<bits/stdc++.h>
using namespace std;
//a[]为递增序列,x为欲查找的数,函数返回第一个大于等于x的元素的位置
//二分上下界为左闭右闭的[left,right] ,传入的值为[0,n] 
int lower_bound(int a[],int left,int right,int x){
	int mid;//mid为left和right的中点 
	while(left<right){
		mid=(left+right)/2;//取中点 
		if(a[mid]>=x){//中间的数大于等于x 
			right=mid;//往左区间[left,mid]查找 
		}else{//中间的数小于x 
			left=mid+1;//往右子区间[mid+1,right]查找 
		} 
	}
	return left;//返回夹出的位置 
}
int main(){
	const int n=11;
	int a[n]={1,3,4,6,7,7,7,8,10,11,12};
	printf("%d",lower_bound(a,0,n,7));
	return 0;
}

找出第一个比它大的数字位置:

#include<bits/stdc++.h>
using namespace std;
//a[]为递增序列,x为欲查找的数,函数返回第一个大于x的元素位置
//二分上下界为左右闭的[left,right],传入的初值为[0,n]
int upper_bound(int a[],int left,int right,int x) {
	int mid;// mid为left和right的中点
	while(left<right) {
		mid=(left+right)/2;//取中点
		if(a[mid]>x) { //中间的数大于x
			right=mid;//往左子区间[left,mid]查找
		} else { //中间的数小于等于x
			left=mid+1;//往右子区间[mid,right]查找
		}
	}
	return left;//返回夹出来的数
}
int main() {
	const int n=11;
	int a[n]= {1,3,4,6,7,7,7,8,10,11,12};
	printf("%d",upper_bound(a,0,n,7));
	return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值