基于C语言的二分法查找

引言

之前我们讲过猜数字游戏,那么假若有一个数字,位于0~100之间,我们该怎么找到他呢?我想这里有两个办法:遍历法、二分法。接下来我们,我们来探讨以下这二者的优缺点。

遍历法

顾名思义,遍历法就是从这组数据的第一位开始找起,遇到我们所需要的数停止。那么很明显,这样带来的最大问题就是慢!固然,计算机的运算速度很快很快,那么假若我们要查找的这个数目很大呢?是不是还是要从第一个数字开始找起呢?

二分法

在讲述二分法的利弊之前,我们先了解以下什么是二分法!
我们小学或是中学学过,所有的实数都是在是实数坐标系上的,那么我们该如何确定一个数的位置呢?是不是可以用谁和谁之间来说明!
例如:2在1和3的中间,50在49和51的中间!
我们继续来想,假设有一个数位于0~100中间,假设这个数字是70,那么我们该如何用上面的思想来找到他呢?
第一次,我猜是50,那么答案很明显不是50,但是,50是不是把这个0-100分成了0-50和50-100两部分。那么70是不是位于50-100这个部分呢?
第二次,我猜是75,这一次,是不是这个部分就变成了50-75呢?

以此类推,我是不是用这种方法确定了70的位置。
像这种,通过逐次的把数据段二等分的方法就叫做二分法!
!!!是不是茅塞顿开了!!!
okok那怎么实现这个过程呢?
我们继续看上面这段话:
第一次,我猜是50,那么答案很明显不是50,但是,50是不是把这个0-100分成了0-50和50-100两部分。那么70是不是位于50-100这个部分呢?
第二次,我猜是75,这一次,是不是这个部分就变成了50-75呢?

第一次的时候,我们是不是取了0和100的中间数50,我们是不是经过了一次比较!比较的是中间数和我们预想的数!,我们是不是因为中间数比我们所想的那个数要小,因此把新线段(这里仅供方便理解)的左端变成了中间数,那么同样的道理,假若中间数要比我们所想的数大,是不是可以把线段的右端的数变成中间数,逐次循环,直到左边的数比右边的数大了!!!
经过了上述的分析,我相信你已经可以写出这段代码了!下面是我的代码,仅供参考:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	scanf("%d", &k);
	//查找-二分查找
	int left = 0;
	int right = sz - 1;
	int find = 0;//假设找不到

	while (left<=right)
	{
		int mid = left + (right-left)/2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,下标是%d\n", mid);
			find = 1;
			break;
		}
	}
	if (find == 0)
	{
		printf("找不到了\n");
	}
	return 0;
}

到了这里,其实我们也可以很明显的感受到一个问题,那就是二分法只能适用于有序数组,假设是一个无序数组,那么这种方法就没办法使用了。
那么如何把一个无序数组变成一个有序数组呢?我们冒泡算法见!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值