二分搜索法

一、问题描述:给定n个元素,这些元素是有序的,从数组中查找特定的元素x。

个人觉得二分法搜索是分治法里面最简单的一个搜索算法了,就是设置一个下界low和上界high,然后再设一个指针mid ( mid=(low+high)/2 ),然后随着每次搜索mid会在两个区间之间( [low,mid-1] 和 [mid+1,high] )进行移动,对应的,low或者high也要相应地改变位置。**要注意这里mid是数组下标而不是一个值。**如图:

二分搜索法_第1张图片

具体一点,就拿上面这个例子来说:首先,二分查找是要在有序的条件下进行的,习惯就先把数组定为升序吧(调用sort()函数即可)。然后初始化完成之后,先判定low<=high是否成立,是,则判断要找的元素x跟mid所对应的数组元素的值是否相等(之后详见算法);否,则算法结束。

二、核心算法:

int BinarySearch(int n, int s[], int x){   
	//n代表元素个数,s[]代表有序数组,x为特定查找元素
	int low = 0;
	int high = n-1;
	while (low <= high){
		int mid = (low+high)/2;
		if(x == s[mid]){
			return s[mid];
		} else if(x < s[mid]){  
			//从前半部分查找
			high = mid-1; 
		} else if(x > s[mid]){
			//从后半部分查找
			low = mid+1; 
		}
	}
	return -1;
} 

继续思考,还有一种递归的方法可以用来表示二分搜索,代码如下:

int RecursionBS(int s[], int x, int low, int high){
	if(low > high){
		return -1;
	}
	int mid = (low + high )/2;
	if(x == s[mid]){
		return mid;
	}else if(x < s[mid]){
		return RecursionBS(s, x, low, mid - 1);
	}else if(x > s[mid]){
		return RecursionBS(s, x, mid + 1, high);
	}
} //注释可以参考上面的非递归注释,是一样的

结合到实例中的算法:

#include 
#include 
#include 
#include 

using namespace std;
const int M = 1005;
int x,n,i;
int s[M];

int BinarySearch(int n, int s[], int x){   
	//n代表元素个数,s[]代表有序数组,x为特定查找元素
	int low = 0;
	int high = n-1;
	while (low <= high){
		int mid = (low+high)/2;
		if(x == s[mid]){
			return s[mid];
		} else if(x < s[mid]){  
			//从前半部分查找
			high = mid-1; 
		} else if(x > s[mid]){
			//从后半部分查找
			low = mid+1; 
		}
	}
	return -1;
} 

int main( void ) {
	cout<<"数组中的元素个数为:"<<endl;
	while(cin >> n){
		cout<<"请依次输入数组中的元素:"<<endl;
		for(i=0; i<n; i++){
			cin >> s[i];
		}
		sort(s,s+n);
		cout<<"排好序的数组如下:"<<endl;
		for(i=0; i<n; i++){
			cout<<s[i]<<" ";
		}
		cout<<"请输入要查找的元素:";
		cin >> x; 
		i = BinarySearch(n,s,x);
		if(i == -1){
			cout<<"没有该元素"<<endl;
		}
		else {
			cout<<"该元素在第"<<i+1<<"位"<<endl;
		}
	}	
	return 0;
}

时间复杂度为:O(nlogn)

不论什么算法,细节都还是挺多的,特别是关于数组的,下标比较容易出错,特别是要能敲出来并且正确运行,还得再细心点

你可能感兴趣的:(算法,算法,二分法)