插值查找
1、概述
插值搜索类似于人们搜索电话的方法名称的目录(书籍条目排序的关键字值):
在每个步骤中,算法计算剩余搜索空间中的位置,根据搜索边界处的关键字值,搜索项可能是空间和搜索关键字的值,通常通过线性插值。然后将在该估计位置实际找到的关键值与所寻求的关键值。如果不相等,则取决于相比之下,剩余的搜索空间被减少到或在估计位置之后。只有在计算关键值之间的差异大小是合理的。
实现
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
/**
* @namespace search
* @brief 搜索算法
*/
namespace search
{
/**
* @namespace binary_search
* @brief 插值查找算法
*/
namespace interpolation_search
{
/**
*@brief 实现插值搜索的主函数
*@param arr要搜索的向量
*@param 要搜索的val值
*@return 向量arr中val的索引
*/
int interpolationSearch(const std::vector<int>& arr, int number)
{
int size = arr.size();
int low = 0, high = (size - 1);
while (low <= high && number >= arr[low] && number <= arr[high])
{
if (low == high)
{
if (arr[low] == number)
{
return low;
}
return -1;
}
// 在考虑均匀分布的情况下探索黄金比例位置 0.618
int pos = low + (high - low) / (arr[high] - arr[low]) * (number - arr[low]);
if (arr[pos] == number) // 找到目标
{
return pos;
}
if (arr[pos] < number) // 节点在区间[arr[pos], arr[high]]之间
{
low = pos + 1;
}
else // 节点在区间[arr[low], arr[pos]]之间
{
high = pos - 1;
}
}
return -1;
}
void testinterpolationsearch()
{
std::vector<int> arr = { 10, 12, 13, 16, 18, 19, 20, 21, 1, 2, 3, 4, 22, 23, 24, 33, 35, 42, 47 };
std::sort(arr.begin(), arr.end());
int number = 33;
int derived_answer = search::interpolation_search::interpolationSearch(arr, number);
std::cout << "元素33位于动态数组中的第[" << derived_answer << "]位" << std::endl; // 15
}
} // namespace interpolation_search
} // namespace search
int main()
{
search::interpolation_search::testinterpolationsearch();
return 0;
}