近期研习C语言,谭浩强《C语言程序设计(第2版)》P167.6原题:
有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“无此数”。
因以前使用其他高级语言时从未使用过该查询算法 ,苦思了有差不多半个钟才代码实现。不过对照原版答案后认为自己的算法更简洁。
原书做法是每一次查找时先根据值的比较结果定出 上界或下界,然后在此范围再提取居中数来做下一步比较。我的实现过程是第一步先取出整个数列居中的数做比较(相当于将取数的“指针”置中),然后根据比较结果将取数“指针”左移或右移,而由于位移量每次比较都会折半,最后当位移量等于0时就无可再移,也就是最后一次进行比较了。
实现代码如下:
#include <stdio.h>
void main()
{
int i, j, n, k=0, isFound=0;
int num[15] = {88,86,75,74,61,56,52,43,39,34,31,22,18,16,8}; //测试数组
printf("请输出一个整数:\n");
scanf("%d", &n);
i = (int)15/2; //对折位移量
j = (int)15/2; //取数“指针”
while(k<2)
{
i = (int)i/2;
if(i == 0) k++; //i==0 即折半到无可再折时,仍有最后一次比较,故以k做计数
//若未相等,计算下一循环指针的位置
if(n<num[j])
j = j + (i + 1);
else if(n>num[j])
j = j - (i + 1);
else
{
isFound = 1;
break; //若找到相等数,标记已找到并退出循环
}
}
//输出结果
if(isFound)
printf("该数是数组中第%d个元素的值\n", j);
else
printf("查无此数!\n");
}
注:
- 理论上在进入查找之前应该先检查所查的数是否在数组范围内,该步工作没有做;
- 关于数组元素个数,除了测试过例题中的15个元素的数组,还加了个元素(16个)也测试通过,即无论元素个数为奇或偶都可以。但未进行更大数量级的测试,若有问题欢迎指正!