二分法数据查找(也称折半查找)
实际并没那么实用的简单查找方法
1.在一个数组中查找数据v时,从中间开始查找,若大于v,则v在前半段,否则在后半段。
2.若在前半段,则将中间数作为数据尾,否则将作为数据始。
3.重复以上流程。
注意,使用二分法时数组必须已经排序好。
例题:OJ2506《数据结构与算法》第6章 折半查找
Time Limit: 1 Sec Memory Limit: 64 MB
Submit: 755 Solved: 223
[Submit][Status][Forum]
Description
从键盘输入n个由小到大的整数,存放到数组a[1]~a[n]中。
编写int BinSearch(int a[ ], int x)函数实现快速查找x的功能,如果查找成功,返回x所在数组元素的下标,否则失败返回0。
Input
输入n
输入n个由小到大的整数
输入要查找的x
Output
如果查找成功,返回元素所在的数组下标,否则失败返回0。
Sample Input
8
2 4 16 28 30 38 45 68
38
Sample Output
6
HINT
要求使用折半查找算法。
题目很简单,要求二分法简单查找数据并返回,但是需要注意的是在查找时对数据的处理方法需要内外一致,下面将根据代码实例说明。
下面是错误示范
#include<stdio.h>
int n;
int BinSearch(int a[],int x)
{
int lift=0,right=n,middle;
while(1)
{
if(lift>right)
return 0;
middle=(lift+right)/2;
if(x>a[middle])
lift=middle;
else if(x<a[middle])
right=middle;
else return middle;
}
}
int main()
{
int i,x,a[100000];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&x);
printf("%d",BinSearch(a,x));
return 0;
}
在BinSearch函数中lift和right的范围是左闭右开类型,即[1,n),当输入的数刚好等于n时,将无法找到。所以循环内也应当统一设为左闭右开类型。
以下为正确代码
#include<stdio.h>
int n;
int BinSearch(int a[],int x)
{
int lift=1,right=n,middle;
while(1)
{
if(lift>right)
return 0;
middle=(lift+right)/2;
if(x>a[middle])
lift=middle+1;
else if(x<a[middle])
right=middle-1;
else return middle;
}
}
int main()
{
int i,x,a[100000];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&x);
printf("%d",BinSearch(a,x));
return 0;
}
注意:此处由于整型数据趋于小数,所以right=middle-1处可写作right=middle
虽然可以AC,但不尽规范。