关于二分查找/折半查找

道 · 引(引例)

一天小明考完试拿到成绩后,让小红猜一猜他考了多少分,并给出范围在56~65之间,小红随即问道你合格了吗??虽然这是扎心的一问,但我们可以窥见二分查找的思想在生活中广泛应用,小红根据小明的回答即可缩小一半的判断范围,不出几次小红便可锁定小明考取的分数,而不会选择遍历的思路,从56,57,一直猜到 65。

道 · 艺(规律方法)

我们在生活中不知不觉使用到了二分查找的方法,在编程刷题中也会遇到这一类型的题,那么该如何解决这一类型的题目呢,从而更好地指导我们的生活和学习。
首先二分查找的对象必须有序,即升序或降序排列,但注意此处有序不一定为等差(此处容易误判),其次我们通常使用数组来存储要处理的数据,则需要对元素下标进行处理,其步骤如下

  1. 找到中间元素k,其下标为mid
  2. 中间元素k和目标元素比较大小,确定新的查找范围,更换k值和mid值
  3. 返回上述两步直至找出或者耗尽查找范围

道 · 试(代码演示)

以小明,小红例子为例:每次用中间的分数缩小范围,找出小明分数的下标

#include<stdio.h>
int main()//二分查找
{
	int arr[10] = { 56, 57, 58, 59, 60, 61, 62, 63, 64, 65 };
	int left = 0, right = 9, mid=0;//起始最左最右端数据下标
	int score = 0, i, j;
	scanf("%d", &score);//录入小明取得的分数
	while (left <= right)//循环缩小判断范围,折半寻找
	{
		mid = (left + right) / 2;//求出中间下标再与score比较缩小范围
		if (arr[mid]<score)//所猜的中间值比实际值小
		{
			left = mid+1;
			continue;
		}
		else if (arr[mid]>score)//所猜的中间值比实际值大
		{
			right = mid-1;
			continue;
		}
		else//所猜的中间值与实际值相等
		{
			printf("找到啦,你的分数是%d,下标是%d\n", arr[mid],mid);
			break;
		}
	}
	if (left > right)
	{
		printf("你猜的分数超过范围啦\n");
	}

	return 0;
}

运行结果如下

当输入分数为65:
当输入分数为65
当输入分数超出范围:
在这里插入图片描述

道 · 味(总结回味)

提问:为何代码中出现的是 left = mid+1 和 right = mid-1 ?
释疑:求中间值下标是用到 mid = (left + right) / 2,这里的“ / ”号是除法取整,即9/2=4
则在算新的left和right时要加一与减一,详见图解。
见图解
当 arr[mid]<score 即所猜的中间值mid比实际值score小,此时left右移至mid+1
在这里插入图片描述
当 arr[mid]》score 即所猜的中间值mid比实际值score大,此时right左移至mid-1
在这里插入图片描述
总结

  1. 学习到了如何用二分查找的方法提高查找效率,其时间复杂度为O(log2n),远优于遍历法
  2. 清晰了写代码时的易错点,为何有left = mid+1 和 right = mid-1 ,以及循环进行的条件left <= right中必有”=“号,因为此时所猜的中间值与实际值相等,也在循环内
  3. 当找不到所给数据时如何处理:if (left > right)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值