如果从文件中读取的数据记录的关键字是有序排列的,则可以用一种效率比较高的查找方法来查找文件的记录,这就是折半查找法,又称为二分法搜索。
折半查找的基本思想是:减小查找序列的长度,分而治之地进行关键字的查找。
假设数组元素呈升序排列。
将 n 个元素分成个数大致相同的两半,取 a[n/2] 与欲查找的 x 作比较,
如果 x = a[n/2] 则找到x,算法终止。
如果 x < a[n/2],则我们只要在数组 a 的左半部继续搜索 x。
如果 x > a[n/2],则我们只要在数组 a 的右半部继续搜索 x。
折半查找的实现过程是:先确定待查找记录的所在范围,然后逐渐缩小这个范围,直到找到该记录或查找失败(查无该记录)为止。
例如有序列: 7 14 18 21 23 29 31 35 38 52(该序列包含 10个元素,而且关键字单调递增。),现要求查找关键字 key 为 38 的记录。
我们可以设指针 low 和 high 分别指向关键字序列的上界和下界,指针 mid 指向序列的中间位置,即 mid = (low+high)/2。
7 14 18 21 23 29 31 35 38 52
↑ low ↑ mid ↑ high
(mid=(low+high)/2)
循环实现:
int BinarySearch(Type a[],const Type& x,int n)
{
int left = 0;
int right = n - 1;
while(left <= right){
int middle = (left + right) / 2;
if (x == a[middle]) return middle;
if (x > a[middle]) left = middle + 1;
else right = middle - 1;
}
return -1;
}
递归实现:
int binary_search(Record *r, const int &low, const int &high, const Key &k)
{
if (low < high)
{
int mid = (low + high) / 2;
if (k == r[mid])
return mid;
if (k < r[mid])
binary_search(r, low, mid, k);
else
binary_search(r, mid + 1, high, k);
}
else if(low == high)
{
if (k == r[low])
return low;
else
return -1;
}
else
return -1;
}
迭代实现:
int binary_search(Record *r, const int &size, const Key &k)
{
int low = 0, high = size - 1, mid = 0;
while(low < high)
{
mid = (low + high) / 2;
if (k > r[mid])
low = mid + 1;
else
high = mid;
}
if (low > high)
return -1;
else
{
if (k == r[low])
return low;
else
return -1;
}
}