一.问题具体要求

定义一个有序数组,再输入一个n,如果数组中存在n就把n的下标输出,如果到数组最后的元素都没有找就输出“找不到”

二.解决思路

1.顺序查找法(for循环从头开始找)

写一个循环从数组的第一个元素开始比较,一直比到想要找到的数字找到后把他的下标输出,如果一直到最后的元素都没有找就输出“找不到”,很明显这里可以用一个for循环加一个if判断语句就可以实现。

#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5,6,7,8};
int n;
scanf("%d",&n);
int ge=sizeof(a)/sizeof(a[0]);//数组的第一个元素下标是0,这样可以求出数组中有多少个元素
int i=0;
printf("数组a内的元素有%d个\n",ge);
for (i=0;i<ge;i++)//i从0开始,所以就让i代表数组的下标
{
if(n==a[i])
{
printf("找到了,%d的下标是%d\n",n,i);
break;
}
}
if(i>ge-1)//i从0开始,其实在这个程序中数组中最后一个元素的下标是ge-1
{
printf("找不到\n");
}
return 0;
}

运行结果是:

     

C语言顺序查找、折半查找在一个有序数组里查找某个数字n的下标_二分法

运行结果正确,但是我们也能看出来,这种方法仅仅适用于数组中元素较少的情况,因为这个for循环是要从第一个元素一直找到n,如果n是最后一个元素,那么就需要循环到最后,效率太低了,是要我们就要找一种更好一点的方法,接下来介绍另一种方法


2.折半查找法(二分法)

C语言顺序查找、折半查找在一个有序数组里查找某个数字n的下标_中位数_02

先来介绍什么是二分法,看上图,其实很简单就是可以理解为找中位数,比如我想找到8,那么我们来分析:首先中位数我们要看下标来找,从1~10中找,先是(0+9)/2=4.5,在C语言中取整为4,那么下标为4的元素就是5,而5比8要小,那么这时我们就要从6~10之间找(因为5已经找了,是要从5的后一位6开始找),6的下标是5,那就是(5+9)/2=7,下标为7那么元素就是8,就找到输入的数字,大致了解后,我们来小结一下:


1.二分法是看下标来查找中位数,因此我们要定义下标(分为左下标和右下标)

2.如果中位数小于n,那么左下标要改成中位数后一位的下标,右下标不变

3.如果中位数大于n,那么右下标要改成中位数前一位的下标,左下标不变


举个例子:

#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5,6,7,8};
int n;
scanf("%d",&n);
int ge=sizeof(a)/sizeof(a[0]);//数组的第一个元素下标是0,这样可以求出数组中有多少个元素
int left=0;
int right=ge-1;//最后一个元素右下标是元素个数减一
while(left<=right)
{
int mid=(left+right)/2;
if(a[mid]<n)
{
left=mid+1;//中位数小于n,那么左下标要改成中位数后一位的下标,右下标不变
}
else if(a[mid]>n)
{
right=mid-1;//中位数大于n,那么右下标要改成中位数前一位的下标,左下标不变
}
else
{
printf("找到了,%d的下标是%d\n",n,mid);
break;
}
}
if(left>right)//这里因为while循环中左右下标加减1的原因才会有,都找不到时left>right的情况
printf("没找到\n");
return 0;
}

结果是:

C语言顺序查找、折半查找在一个有序数组里查找某个数字n的下标_中位数_03

   

三.总结


1.顺序查找

优点:在查找前不需要对其做什么处理
缺点:查找速度慢,最糟糕的情况需要从头到尾遍历一遍,时间复杂度是n

2.折半查找

优点:查找速度快,时间复杂度是以2为底n的对数。
缺点:只适用于已经排好序的数列