C语言算法基础之——二分查找法

二分查找

上面我们学了简单查找,并且可以判断输入的数据相比于目标值是大了还是小了。那么举个例子:假如给定100个元素:

 那么假设我们猜的第一个数字是50,如果返回的数据是“猜小了”的话,我们就知道从1~50这些数据都是小于目标值的,那么我们就可以舍去这个范围内所有的数,下一次就在(50~100)中间这个范围内猜:

 那么如果我们下一次猜的数字是75,如果返回的数字是“猜大了”的话,同样,我们就能知道在(75~100)这个范围内的所有数字都是大于目标值的。那么我们就可以在(50~75)这个范围内猜数。以此类推,每一次猜的数都是在此范围内的中间值,而每次都可以排除掉一半的数据,这就是二分查找,下面是实现二分查找的代码举例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	srand(time(0));
	int target = rand() % 100 + 1;
	int left = 1;										//设置左边界
	int right = 100;									//设置有边界
	while (left <= right) {								//当左右边界相等时,即为目标值
		int mid = (right - left) / 2 + left;			//数值过大的时候(right + left) / 2不可用
		if (mid == target) {
			printf("猜对了");
			return 0;
		}
		else if (mid < target) {
			printf("猜小了");
			left = mid + 1;								//如果目标值大于所猜的中间值,则小于等于中间值的部分均不要
		}
		else if (mid > target) {
			printf("猜大了");							//如果目标值小于所猜的中间值,则大于等于中间值的部分均不要
			right = mid - 1;
		}
	}				
	return 0;
}

此段代码中,我们设置了左边界left和有边界right,即在左边界和有边界中间取中间值查找中间值mid = (right - left)/2 + left而使用这种方法设定mid的原因我们在代码中也体现了;当中间值mid小于目标值target时,小于等于mid的值舍去,此时左边界left = mid + 1,而当中间值mid大于目标值target时,大于等于mid的值舍去,此时右边界变right = mid - 1以此类推,当找到中间值时或左边界等于有边界时(这种情况就是所有数都猜完了,就剩最后一个数了此时这个数就是目标数target),输出结果,结束循环。

一般来说在一个有n个元素的列表中,使用二分查找最多需要\log_{2}n步,而简单查找则最多需要n步。

二分查找是一个典型的算法,输入是一个有序地元素列表,二分查找的时间复杂度为O(\log_{2}n)。

例:给定一个升序的数组,含有n个元素,现在有一个目标值target,我们需要在数组中找到目标值,并返回下标,下面是代码:

#include<stdio.h>
#include<stdlib.h>
int Binsearch(int* arr, int target, int n) {				//传递参数有数组,目标值,数组元素数量
	int left = 0;											//定义左右变量
	int right = n - 1;
	while (left <= right) {
		int mid = (right - left) / 2 + left;
		if (arr[mid] == target) {
			return mid;
		}
		else if (arr[mid] < target) {
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}
	return -1;													//若没有与目标数target匹配的数组元素,返回值-1
}
int main() {
	int n;
	scanf("%d", &n);											//输入数组元素个数
	int* arr = (int*)malloc(sizeof(int) * n);					//申请堆空间,大小根据数组元素个数而定,为动态空间
	for (int i = 0; i < n; i++) {								//输入数组各个元素
		scanf("%d", &arr[i]);
	}
	int target;													//定义目标值
	scanf("%d", &target);										//输入目标值
	int k = Binsearch(arr, target, n);							//设置二分查找函数,返回值为int类型,返回数据为和目标值相等的数组元素的下标
	printf("%d", k);											//输出数组元素
	free(arr);													//解放堆区空间
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Coke_3.2.2

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

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

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

打赏作者

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

抵扣说明:

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

余额充值