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

代码解析如下:

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

#include
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
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
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;
}

你可能感兴趣的:(c++/c语言 二分法基础代码详解)