目录
引言
代码的作用是在一个升序的数组中,寻找指定的数字n。如果找到了就打印数组中该数字的下标,找不到便提示找不到。
1.常规方法
如果按照正常的思路来说,遍历数组的每一个元素,把每一个元素与n相比较。这样的方法完全可以,下面给大家展示代码。
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
int arr[10];
int i;
int flag = 1;
for (i = 0; i < 10; i++)
scanf("%d", &arr[i]);
for (i = 0; i < 10; i++)
{
if (arr[i] == n)
{
printf("%d", arr[i]);
flag = 0;
break;
}
}
if (flag)
printf("找不到");
return 0;
}
上图为代码,n为我们要查找的数字。数组arr中放着十个升序的数字,整型变量flag为我们设置的一个标记,如果flag的值被改代表在数组中找到了和n一样的数字。然后在for循环中我们遍历整个数组,把每一个元素与n比较,如果找到了,则跳出循环并且改变flag的值,flag的值被改变后,最后的if语句则不会打印找不到。这就是整个代码的逻辑。
2.二分查找
上面的代码可以完成目标,但是当数组的元素量过大时,程序可能要搜寻很久才能完成工作,这样一来,代码的效率就变得很低。而二分查找能够大大提高代码的效率。
2.1二分查找的逻辑
因为数组是一个升序的数组,我们可以定义三个整形变量,一个代表数组最左边的元素,一个代表数组最右边的元素,一个代表数组最中间的元素。把n与最中间的元素对比,如果这个最中间的元素比n大,说明这个数组中间到最右边的元素都比n大,那么就没必要再拿这些元素与n相比较,他们一定跟n不一样,那么我们就要从最左边到中间元素的范围中寻找,然后我们在求出这个范围的中间元素然后跟n比较,每一次比较都减小一半范围,这样就能够大大提升代码的效率。
2.2二分查找的实现
我们直接上代码
#include<stdio.h>
int bin_search(int arr[],int a)
{
int left = 0;
int right = 9;
int mid;
int d=1;
while (left<=right)
{
mid = (left + right) / 2;
if (arr[mid] > a)
{
right = mid - 1;
}
else if (arr[mid] < a)
{
left = mid + 1;
}
else
{
d = 0;
return mid;
}
}
if (d == 1)
return -1;
}
int main()
{
int arr[10];
int i = 0;
int a;
scanf("%d", &a);
for (i = 0; i < 10; i++)
scanf("%d", &arr[i]);
int b = bin_search(arr, a);
if (b!=-1)
{
printf("找到了下标是:%d", b);
}
else
printf("找不到");
return 0;
}
在代码中我们分装了一个bin_search函数来实现查找的功能,left变量代表数组最左边的元素,right变量代表数组最右边的元素,mid变量代表数组中间的元素,d变量是我们设置的一个标记,如果d的值被改变,就代表在数组中找到了相同的元素。下面我们举例子对函数中循环逻辑来进行解示
2.2.1函数中循环逻辑的解释
我们假设要查找的数字为7,数组中的元素为1-10。最初三个变量位置如图,第一次进入循环时,n>mid,所以改变left为mid+1,然后再进入循环后会重置mid为left和right的中间值,然后第二次查找,n<mid所以改变right的值为mid-1。然后再从头开始改变mid的值,然后第三次循环,n>mid所以再改变left的值为mid+1,此时mid、left、right为同一值,这次发现mid的值和n一样 所以程序会return mid 并改变d的值来说明找到了。while循环的条件为left<=right,因为在最后三个值会相等,如果还找不到的话,left和right就会错开,left就会大于right,那么就说明找不到,while循环停止,这就是while循环的整个逻辑。
完