线性查找就是把要查找的关键字与数组中的元素逐个进行比较来进行查找;
而对于有序排列的数组而言,折半查找把要查找的关键字先与数组中间的元素进行比较,如果相同就可以结束查找;如果不同的话,比较关键字和中间元素的大小,关键字大于中间元素的话就在数组后半边查找,小于中间元素的话就在数组前半边查找。
线性查找适合于规模较小的数组或者无序排列的数组。对于有序排列的大规模数组而言用线性查找的方法可能非常慢。
举例而言,有个有序排列的数组,从1到2047有元素个数2047,我们采用折半查找,最坏的情况只需要进行11次比较。因为我们先和(1+2047)/2=1024比较,再和(1023+1)/2=512比较,再和256、128、64、32、16、8、4、2、1比较。而如果我们用线性查找的话,最坏情况下需要比较2047次。数量再大一些,这两种方法的差距就会更大。有2的n次方减一个元素,线性方法就要比较2的n次方减一次,而折半查找只需要n次。
下面是一个利用折半查找法的例子:
#include<stdio.h>
#define SIZE 15/*定义数组的大小*/
int binary(const int a[],int searchKey,int low,int high);/*折半查找*/
void guocheng(const int a[],int low,int mid,int high);/*打印每次查找的子数组,并把中间值后面用*标记*/
int main(void)
{
int a[SIZE];
int i;
int key;
int result;
for (i=0;i<SIZE;i++)
{
a[i]=2*i;
}
printf("请输入一个数字(0~%d)",(SIZE-1)*2);
scanf("%d",&key);
printf("元素号为:\n");
for(int i=0;i<SIZE;i++)
{
printf("%3d ",i);
}
printf("\n");
for (int i=1;i<=SIZE;i++)
{
printf("___ ");
}
printf("\n");
result=binary(a,key,0,SIZE-1);
if(result==-1)
{
printf("找不到%d",key);
}
else
{
printf("在位置%d处找到%d",result,key);
}
}
int binary(const int a[],int searchKey,int low,int high)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
guocheng(a,low,mid,high);
if (searchKey==a[mid])
{
return mid;/*在数组中找到了关键字,就返回mid值*/
}
else if(searchKey!=a[mid])
{
if (searchKey>a[mid] )
{
low=mid+1;
}
else
{
high=mid-1;
}
}
}
return -1;/*在数组中没找打这个关键字,就返回-1*/
}
void guocheng(const int a[],int low,int mid,int high)
{
for (int i=0;i<SIZE;i++)
{
if(i<low||i>high)
{
printf(" ");
}
else if(i==mid)
{
printf("%3d*",a[i]);
}
else
{
printf("%3d ",a[i]);
}
}
printf("\n");
}