折半查找法
1.优点在于比较的次数比较少,对于想要查找的数能够快速的找到,耗费的时间比较少。
2.缺点在于这个方法是要求待查找的表为有序的,并且插入删除比较的困难。
一.用一维数组进行举例:
例如,一个一维数组a[10]={2,5,7,8,9,15,20);在这个数组中查找key=15的位置。(因为是举例,所以这个数组是有序的,如果碰到无序的数组,可以先排个序,但其实有排序的那个功夫,估计遍历一遍也就能找到了。所以不建议在无序的时候用,会更耗费时间)
如图所示,将最小的数据记为low,最大的数据记为high,中间的值记为mid;(如果mid不是整数,就要进行取整)
用二分法查找的时候,先将所要查找的key的值与mid作比较,例如在这个例子中就要将8与15进行比较,8比15小,因此便将范围缩小在了【8,20】这个区间里面。然后在这个区间里用继续用上述方法;
c语言代码如下:
#include<stdio.h>
int search(int a[],int n,int key)
{
int low=0;
int high=n-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(key==a[mid]);
return mid;
if(key>a[mid])
low=mid+1;
else high=mid-1;
}
return -1;
}
int main()
{
int a[]={2,5,7,8,9,15,20};
printf("%d",search(a,7,15));
return 0;
}
二. 用二维数组进行折半查找。
既然用二位数组进行查找,那么就意味着二维数组每一行,每一列都是有序的。
例:存在一个3*5的二位数组,他的每一行,每一列都是递增的,如图
因为每一行都是递增的所以我们最开始以右上角的数字9为基准,我们将需要查找的数字与数字9进行比较,如果比9大,那么将数字9的列不变,行数加一,即相当于跳到了数字12.下来再将要查找的数字与数字12比较,如果比12小,那么数字12的行数不变,列数-1.然后不断重复上述过程,便可以找到。
注意:循环终止的条件:1是找到了所要找的数字,终止。2是没有找到,终止,当没有找到数字时会有两种可能,行数一直加,超过了数组边界或者列数一直减少,超过了边界。
完整代码如下:
#include<stdio.h>
int main()
{
int n,m,key,i,j;
int a[10][10];
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d",&key);
i=1;j=m; //将与key作比较的点选为右上角
while(i<=n&&j>=1)
{
if(a[i][j]==key)
{
printf("%d %d",i,j);
return 0;
}
if(a[i][j]<key)
i++;
else j--;
}
printf("-1"); //找不到则输出-1
return 0;
}