二分查找算法(折半查找算法)的实现

在一个有序数组中查找具体的某个数字

二分查找只能适用于有序的数组

首先,我们先给定一个数组 arr[10]={1,2,3,4,5,6,7,8,9,10}
如图所示

在这里插入图片描述

因为下标都是从0开始的,所以我们定义数组的左下标为 left = 0
如果我们不知道数组中元素的个数,那么我们便无法知道右下标,但是通过计算得到数组中元素的个数。
sizeof 可以计算数组所占空间的大小,所以 元素个数 = sizeof( arr[] )/sizeof( arr[0] ),即数组所占总空间大小/一个元素所占空间大小。注意arr[0]表示的是数组中的第一个元素,所以sizeof( arr[0] )是指一个元素所占空间的大小。那么数组的右下标为 right = sizeof( arr[] )/ sizeof( arr[0] ) - 1.
如图所示

在这里插入图片描述那么我们所寻找元素下标的范围就在 left ~ right 之间,包含 left 与 right 。
那么中间元素的下标 mid = ( left + right ) / 2 即 mid = ( 0 + 9 ) / 2 = 4

在这里插入图片描述
假设我们查找的数字为 k
那么下表 mid 所对应的元素是 arr[4], 如果 arr[4] < k,说明元素 k 的下标在 4 ~ right 之间,不包含4,如果arr[4] < k,那么元素k的下标范围是 left ~ 4 之间,不包含4。
假设 k = 7 , arr[4] < 7, 所以查找元素在元素arr[4]d的右边
此时 left = mid + 1
如图

在这里插入图片描述
然后根据新的 left 与 right 求出 新的 mid = ( 5 + 9 ) / 2 = 7(下标)
如图

在这里插入图片描述

那么 arr[7] > 7(元素),说明在 left ~7(下标)之间,不包含 7 ,right = mid - 1
如图

在这里插入图片描述然后新的中间元素下标 mid = (5 + 6 ) / 2 = 5, 此时arr[5] < 7, 则 left = mid + 1 = 6
如图

在这里插入图片描述

新的 mid = ( 6 + 6 ) / 2 = 6, 此时 arr[6] = 7 ,所以找到了

总结一下 :
① 确定数组的左右下标 left 和 right
② 根据 left 与 right 确定中间下标 mid
③ 根据 mid 锁定元素并与查找的元素比较,确定新的查找范围即新 left 和 right
④ 重复 ②③步骤,直到找到查询元素为止

废话不多说,上代码

#include<stdio.h>
int main()
{
	int k = 7;
	int arr[] = {1,2,3,4,5,6,7,8,9,10 };   //定义一个数组
	int left = 0;                          //左下标
	int right = sizeof(arr) / sizeof(arr[0]) - 1;    //右下标
	int mid = 0;                                     //中间元素的下标
	while (left <= right)    //只有当left <= right 时,才存在元素与 所查元素比较
	{
		mid = (left + right) / 2;  //求得中间元素下标
		if (arr[mid] == 7)         //当下标锁定元素与所查找元素相等时,跳出循环
		{	
			break;
		}
		else if (arr[mid] > 7)     //当下标锁定元素大于所查找元素时
		{
			right = mid - 1;	   //确定新的右下标
		}
		else
		{
			left = mid + 1;	       //当下标锁定元素小于所查找元素时,确定新的左下标
		}

	}
	                              //此时有两种情况,一种是在循环过程中找到了,break跳出循环来到这
	                              //另一种是循环结束,没找到,来到这,此时left > right
	if (left <= right)            //用来判断是哪一种情况
	{
		printf("找到了,下标是%d \n",mid);
	}
	else
	{
		printf("没找到\n");
	}
	return 0;
}

下面这个用 flag 作为标记来判断是否找到,替代了 (left <= right)

#include<stdio.h>
int main()
{
	int k = 7;
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };   //定义一个数组
	int left = 0;                          //左下标
	int right = sizeof(arr) / sizeof(arr[0]) - 1;    //右下标
	int mid = 0;   //中间元素的下标
	int flag = 0;  //作为一个标记
	while (left <= right)    //只有当left <= right 时,才存在元素与 所查元素比较,用到了while循环
	{
		mid = (left + right) / 2;  //求得中间元素下标
		if (arr[mid] == 7)         //当下标锁定元素与所查找元素相等时,跳出循环
		{
			flag = 1;              //  当找到了flag 变为1,否则flag 为 0
			break;
		}
		else if (arr[mid] > 7)     //当下标锁定元素大于所查找元素时
		{
			right = mid - 1;	   //确定新的右下标
		}
		else
		{
			left = mid + 1;	       //当下标锁定元素小于所查找元素时,确定新的左下标
		}

	}
	//此时有两种情况,一种是在循环过程中找到了,break跳出循环来到这
	//另一种是循环结束,没找到,来到这,此时
	if (flag == 1)         //用以判断是否找到
	{
		printf("找到了,下标是%d \n", mid);
	}
	else
	{
		printf("没找到\n");
	}
	return 0;
}

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值