折半查找

折半查找(Binary Search)是一种减治思想的算法,即每次将问题的规模减半,以达到快速查找到目标元素的目的。因为对于一个有序数组而言(假设是非降序排列的),若数组中间的元素大于目标元素,则其后面的所有元素都是大于目标元素的,因此我们只需要在其前面的元素中查找即可;反之,若数组中间的元素小于目标元素,则其前面的元素都是小于目标元素的,因此我们只需要在其后面的元素中查找即可。

当然,折半查找的前提是,所要查找的数组必须是有序的!!!否则不能使用折半查找。

具体减治法的思想可以参考我的另一篇博文:《减治法》

先上伪代码

因为伪代码没有其他语言的语法限制,能够有助于我们更好地将注意力放在算法上,所以这里我们先用伪代码来讲述一下主要思想:

algorithm binarySearch(A[0..n-1], data)
//使用折半查找算法在升序数组A中找到元素data,有则返回元素的位置,否则返回-1
//输入:一个升序数组A以及待查找元素data
//输出:目标元素的位置或者-1
low <- 0;high <- n-1
while low <= high do
	middle = (low + high) / 2  //向上取最小或者向下取最大都可以,这里向下取最大
	if data = A[middle] return middle
	else if data < A[middle] high = middle - 1  //目标元素小于中间元素,则应该在左边
	else low = middle + 1  //目标元素大于中间元素,则应该在右边
return -1  //找不到就返回-1

代码实现

折半查找算法:

int binarySearch(int* data, int n) {
	int low = 0;
	int high = 9;
	while (low <= high) {
		int middle = (low + high) / 2;
		if (data[middle] == n) return middle + 1;
		else if (data[middle] < n) low = middle + 1;
		else high = middle - 1;
	}
	return -1;
}

然后在main函数中运行:

int main() {
	int data[10] = { 1, 3, 4, 5, 7, 8, 12, 35, 44, 57 };
	cout << "2在数组中的位置:" << binarySearch(data, 2) << endl;
	cout << "12在数组中的位置:" << binarySearch(data, 12) << endl;
	return 0;
}

运行结果如下:

在这里插入图片描述

时间复杂度分析

最优情况:即刚好出现在middle位置上,那么时间复杂度为O(1)

最差情况:即刚好要等到low=high时,才能够确定是否存在,则时间复杂度为O(logn)

那么是否查找算法已经无法再进一步优化了呢?

不!还有一种比它更好的算法——插值查找,它的复杂度为O(loglogn)。

请参考我的另一篇博文《插值查找——一个比折半查找更好的查找算法》

参考资料

《算法设计与分析基础》第三版以及老师的课件

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花无凋零之时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值