一般数据结构教程中的折半查找算法,只是在找到欲查找的元素时,返回的下标才有效。
但是在一些工程计算中,一般情况下要查找的元素在数组中都是不存在的,需要做插值计算,这种情况下,就需要对折半查找算法做一些修改。
在Win10中使用VS2022实现了一种便于插值计算的折半查找算法。
在VS2022中新建C++空项目,添加源文件“main.cpp”,输入如下代码:
#include <iostream>
// D是指向数据的指针,nCount是数据的个数.
// ind, 当函数返回true时起作用,即找到元素的下标
// a, 是要查找的目标值
// iL和iR,当函数返回false时,起作用.
// 返回值:true,表示a在数组D中;false,表示不在
bool myBinarySearch(double *D, int nCount, double a, int& ind, int& iL, int&iR) {
int s = 0, e = nCount - 1, m = 0; // 开始、结束、中间下标.
bool bFind = false;
while (s <= e) {
m = (s + e) / 2;
double mv = D[m];
if (mv == a) {
bFind = true;
ind = m;
return true;
}
else if (mv < a)
s = m + 1;
else
e = m - 1;
}
iL = e;
iR = s;
return false;
}
int main()
{
// 向D中写入数据.
int nCount = 10;
double* D = new double[nCount];
for (int i = 0; i < nCount; i++) {
D[i] = i * 10;
}
// 显示D的值。
std::cout << "D的值:" << std::endl;
for (int i = 0; i < nCount; i++) {
std::cout << D[i] << " ";
}
std::cout << std::endl;
// 以下是测试myBinarySearch的代码.
bool bFind = false;
int ind=0, indL=0, indR=0;
double a = 80;
std::cout << "查找" << a << ". 预期结果:bFind=true,ind=8" << std::endl;
bFind = myBinarySearch(D, nCount, a, ind, indL, indR);
std::cout << "实际结果" << ":bFind="<< bFind << ",ind = " <<ind<< std::endl;
a = 75;
std::cout << "查找" << a << ". 预期结果:bFind=false,indL=7, indR=8" << std::endl;
bFind = myBinarySearch(D, nCount, a, ind, indL, indR);
std::cout << "实际结果" << ":bFind=" << bFind << ",indL = " << indL << ",indR = " << indR << std::endl;
a = -1;
std::cout << "查找" << a << ". 预期结果:bFind=false,indL=-1, indR=0" << std::endl;
bFind = myBinarySearch(D, nCount, a, ind, indL, indR);
std::cout << "实际结果" << ":bFind=" << bFind << ",indL = " << indL << ",indR = " << indR << std::endl;
a = 100;
std::cout << "查找" << a << ". 预期结果:bFind=false,indL=9, indR=10" << std::endl;
bFind = myBinarySearch(D, nCount, a, ind, indL, indR);
std::cout << "实际结果" << ":bFind=" << bFind << ",indL = " << indL << ",indR = " << indR << std::endl;
return 1;
}
代码实现中,函数myBinarySearch实现了便于插值计算的折半查找算法,当函数返回值为true时,ind的值可用,D[ind]就是要查找的目标值a;返回值为false时,iL和iR的值可用,当iL和iR的值都在0到nCount-1之间时,可以使用D[iL]和D[iR]的值做内插值计算,否则,可以做外推计算(当然是根据实际需要确定是否做外推计算)。
main函数主要是生成数据,并用数据对函数myBinarySearch的正确性(即是否满足需求)做检验。程序的运行结果如下图所示:
实际运行结果与预期结果一致,说明了程序实现的正确性。