©作者:凡人编程传
©系列:C语言初阶(适合小白入门)
©说明:以凡人之笔墨,书写未来之大梦
卐前言
因为昨天有点忙碌所以上一节的压轴题放在了这一节,这一节是满满的干货,不管是小白还是已经对C语言掌握大概的人都可以有颇多收获,这一节的练习题可能对小白来说难度有点大,我会尽量讲的详细一点,希望你们都会有收获!
卐压轴题
题目:给定一个有序数组,如1,2,3,4,5,6,7,8,9,10.编写程序查找数字7,若有该数字输出找到了并且打印该数字下标,否则,输出找不到。
题目分析:有的小白可能认为这道题无非就是遍历数组查找就行了,虽然遍历数组的确可以实现,但是有100000个元素的数组也然你查找其中一个数字那么遍历数组的效率是不是太低了?所以这里我们用到一个算法——二分查找法。这个算法查找的前提是数组要是有序的,且元素是不重复的。这道题的数组刚刚好是升序那么接下来让我说一下这个二分查找法。
二分查找法的主要思想:在有序表中,我们取中间元素作为被比较对象,若目标值(我们想要查找的值)刚好与中间值相等,则查找成功;若目标值小于中间值,则在中间值的左半边继续查找;若目标值大于中间值,则在中间值的又半边继续查找。不断重复上述过程,直到查找成功。或所有查找区域均无记录,则查找失败。
我们不妨想想,我们要在数组里面查找数字7,而数组里面的元素都是有下标的.那么是不是我们要先找到他的中间元素的下标,那么光找到中间元素就行了吗?显然不行吧。算法思想是中间元素和要查找的数字比较来确定要查找的数字是在中间元素的左边还是右边,若是在右边我们左半边的查找范围就可以缩小。若在右边,右半边的范围就可以缩小。最后注意一点,虽然算法效率的确很高。但是也不至于一次就找到,是不是也要考虑循环呀。
好了文字描述这么多,大家可以看一下图来结合或许可以更懂一些:
好了,到这多少都懂了些了吧。直接上代码了!
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7; //要查找的数字
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1; //40/4=10 , 10-1=9.刚好是10的下标
while (left <= right) //我们要直到查找到左右下标同时指向一个元素
{
int mid = (left + right) / 2; //中间元素下标. 注意:每次中间元素都在变所以要放在循环里面重新更新.
if (arr[mid] > k) //中间元素比要查找的数字大(查找数字在左边)
{
right = mid - 1; //缩小右边查找范围
}
else if (arr[mid] < k) //中间元素比要查找的数字小(查找数字在有边)
{
left = mid + 1; //缩小左边查找范围
}
else
{
printf("找到了!下标是%d", left); //注意这里一定要加上break跳出来,否则后面找到了左右下标不变会导致left<=right恒成立形成死循环.
break;
}
}
if (left > right)
{
printf("找不到\n");
}
return 0;
}
运行结果:
卐结言
好了,对二分查找法的叙述就到这。希望你有收获。我们下节见