【问题描述】
应用折半查找方法在一个有序序列中查找值为k的记录;查找成功,返回记录k在序列中的位置。
【分析】
折半查找(binary search)利用了记录序列有序的特点,其查找过程是:取有序序列的中间记录作为比较对象,若给定值与中间记录相等,则查找成功;若给定值小于中间记录,则在中间记录的左半区继续查找;若给定值大于中间记录,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功;其减治思想如图所示。
例如,在有序序列{7,14,18,21,23,29,31,35,38}中查找18。
【算法】
折半查找算法用伪代码描述如下。
输入:有序数列a[n],待查找区间[l,r],待查找值k;
输出:查找成功,返回k的位置,
划分区间m=(l+r)/2
将区间分为两部分,[l,m], [m+1,r]
如果k<m,则对左半区间进行查找,递归
如果k>m,则对右半区间进行查找,递归
如果k=m,则查找成功,返回该元素对应的下标
【算法实现】
#include<stdio.h>
int search(int a[], int l, int r, int k)
{
int m = (l + r) / 2; //划分区间
if (a[m] == k) return m; //递归出口
else if (a[m] > k)
{
search(a, l, m - 1, k); //查找左区间
}
else if (a[m] < k)
{
search(a, m + 1, r, k); //查找右区间
}
}
int main()
{
int k;
int a[100];
int n;
int l, r;
int result;
printf("序列长度:");
scanf("%d", &n);
printf("待查找数组:");
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("查找区间:");
scanf("%d %d", &l, &r);
printf("要查找的元素:");
scanf("%d", &k);
result = search(a, l, r, k);
printf("该元素的下标为:%d", result);
}
【输出结果】