C++二分法查找

一、二分法思想

二分法查找针对的是一个有序的数据集合,每次通过与区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为0.

故时间复杂度就是O(logn)

二分查找的递归与非递归实现

1、二分查找非递归实现

int binarySearchFirstOne(vector<int> &a, int value) {
	int n = a.size();
	int low = 0;
	int high = n - 1;

	while (low <= high) {
		int mid = low + ((high - low) >> 1);
		if (a[mid] >= value)
			high = mid - 1;
		else
			low = mid + 1;
	}
	if (low < n && a[low] == value) {
		return low;
	}
	else {
		return -1;
	}
}

二分查找易错的地方

    循环退出的条件

    注意是low <= high,而不是low<high.

    mid的取值

    如果写成 mid (low+high)/2是有问题,如果low和high比较大,两者的和可能会溢出改进的方案low+(high-low)/2,但是计算机位运算比除法快,故可改成low+((high-low)>>1)

二分法的递归实现

int bsearchInternally(vector<int>& a, int low, int high, int value)
{
	if (low > high)
		return -1;
	int mid = low + ((high - low) >> 1);
	if (a[mid] == value) {
		return mid;
	}
	else if (a[mid] < value)
		return bsearchInternally(a, mid + 1, high, value);
	else {
		return bsearchInternally(a, low, mid - 1, value);
	}
}

int bsearch(vector<int>& a, int n, int val) {
	int res= bsearchInternally(a, 0, n - 1, val);
	return res;
}

三、二分法查找应用场景

    二分查找依赖顺序表结构

    二分查找不能依赖如链表的的其他结构,主要原因是二分查找算法需要按照下标随机访问元素,链表随机访问的时间复杂度是O(n),使用链表存储,二分查找的时间复杂度就会变得很高

    二分查找针对的有序数组

    二分查找对数据要求必须是有序的,如果数据没有序,则需要先排序

    数据量太小或数据量太大也不适合二分查找

参考:

https://www.cnblogs.com/aeolian/p/9524491.html

https://blog.csdn.net/z_s_z2016/article/details/98470716

猜你喜欢

转载自blog.csdn.net/sinat_31608641/article/details/107600663
今日推荐