简单二分查找的讲解

二分查找是什么?

二分查找又称为折半查找,其优点是查找速度快,缺点是要求所要査找的数据必须是有序序列。

简单来说:就是从中间开始查找

如果中间查找的数大,及从右边开始折半查找

如果中间查找的数小,及从右边开始折半查找

如果中间查找的数等于,及直接输出,不在循环查找

二分查找的基本思路

  1. 在有序表中,每次都取中间元素作为比较对象。
  2. 如果中间值与目标元素相等,则查找成功,返回该元素的下标。
  3. 如果中间值大于目标元素,则在中间值的右半区间继续查找。
  4. 如果中间值小于目标元素,则在中间值的左半区间继续查找。
  5. 确定了该元素所在范围外的元素就不需要继续查找了,不断重复以上过程,直至找到目标元素。

二分查找解题思路

eg:对静态查找表{1,2,3,4,5,6,7,8,9,10}采用折半查找算法查找关键字为 4 的过程为:


图 1 

注意:在做查找的过程中,如果 left 和 right 的中间位置在计算时位于两个关键字中间,即求得 mid 的位置不是整数,需要统一做取整操作。


如上图 1 所示,left 和 right 分别指向查找表的第一个关键字和最后一个关键字, mid  指向处于 left 和 hight 指针中间位置的关键字。在查找的过程中每次都同 mid 指向的关键字进行比较,由于整个表中的数据是有序的,因此在比较之后就可以知道要查找的关键字的大致位置。

例如在查找关键字 4 时,首先同 5 作比较,由于4<5,而且这个查找表是按照升序进行排序的,所以可以判定如果静态查找表中有 4 这个关键字,就一定存在于 left 和 mid 指向的区域中间。

因此,再次遍历时需要更新 right 和 mid 的位置,令 right 移动到 mid 的左侧一个位置上,同时令 mid 重新指向 left 和 right 的中间位置。如图 2 所示:


图 2 

同样,用 4 同 mid 指向的 3 作比较,3 < 4,所以可以判定 4 如果存在,肯定处于 mid 和 right 指向的区域中。所以令 left 指向 mid 右侧一个位置上,同时更新 mid 的位置。
 


图 3 

当第三次做判断时,发现 mid 就是关键字 4 ,查找结束。

二分查找的实现代码:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[0]) - 1;
	int key = 4;//要找的数字
	int mid = 0;//记录中间元素的下标
	int find = 0;//定义个如果找到等于1
	while (left <= right)//如果左边小于等于右边的情况
	{
		mid = (left + right) / 2;//中间元素的下标,使⽤ mid = (left+right)/2;
//如果left和right⽐较⼤的时候可能存在问题,可以使⽤下⾯的⽅式:mid = left+(right-left)/2;
		if (arr[mid] > key)//如果要查找的数下标对应的值大于要查找的数
		{
			right = mid - 1;//及再从左边开始继续查找,
		}
		else if (arr[mid] < key)//如果要查找的数下标对应的值小于要查找的数
		{
			left = mid + 1;//及再从右边开始继续查找,
		}
		else
		{
			find = 1;//如果找到跳出循环
			break;
		}
	}
	if (1 == find)
		printf("找到了,下标是%d\n", mid);
	else
		printf("找不到\n");
}

二分查找总结

二分查找其实还有很多其他的变体应用,但它们基本上是循环条件判断条件边界更新方法的不同组合。加油,相信自己能探索出更多的用法!可以评论一下让我也学学。谢谢

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值