插值搜索和二分搜索都是在有序数组中查找目标元素的算法。它们之间的核心区别在于确定中间元素的方式。
1、二分搜索(Binary Search):二分搜索是一种通过将目标值与数组中间元素进行比较,然后根据比较结果缩小搜索范围的算法。如果中间元素等于目标值,则找到目标;如果中间元素大于目标值,则在左半部分继续搜索;如果中间元素小于目标值,则在右半部分继续搜索。这样不断缩小搜索范围,直到找到目标或确定目标不存在。
2、插值搜索(Interpolation Search):插值搜索是一种根据目标值在已知范围内的分布情况,预测目标值应该在的位置,然后进行搜索的算法。通过计算估计的位置(插值位置),然后进行比较,再根据比较结果缩小搜索范围。插值搜索通常在数据元素分布比较均匀的情况下效果更好,能比二分搜索更快地收敛到目标值。
经过定义理解,二分搜索是通过比较中间元素来划分搜索范围,每次将搜索范围缩小一半;插值搜索是通过估计目标值在数组中的位置,根据估计位置缩小搜索范围。插值搜索在数据分布比较均匀且连续的情况下可能更快,但在非均匀或者不连续的情况下可能不如二分搜索。
对于有序且均匀分布的数组,插值搜索比二分搜索效果更好。
无论搜索键如何,二分搜索都会转到中间元素进行检查。另一方面,插值搜索可以根据搜索关键字去不同的位置。如果搜索键的值接近最后一个元素,则插值搜索可能会向末尾开始搜索。
插值搜索和二分搜索都是用于在排序列表或数组中搜索特定元素的算法。两种算法的平均时间复杂度均为 O(log n),这意味着执行搜索所需的时间随着列表的大小呈对数增长。
但是,插值搜索和二分搜索之间存在一些关键区别:
插值搜索根据目标元素周围元素的值来估计目标元素的位置,而二分搜索总是从检查列表的中间元素开始。
当列表中的元素均匀分布时,插值搜索比二分搜索更有效,而当列表中的元素不均匀分布时,二分搜索更有效。
插值搜索可能比二分搜索需要更长的时间来实现,因为它需要使用额外的计算来估计目标元素的位置。
例子 :
function interpolation_search(arr, target){
let low = 0;
let high = arr.length - 1;
while (low <= high && target >= arr[low] && target <= arr[high]){
// Calculate the position of the target element based on its value
let pos = low + Math.floor(((target - arr[low]) * (high - low)) / (arr[high] - arr[low]));
// Check if the target element is at the calculated position
if(arr[pos] == target){
return pos;
}
// If the target element is less than the element at the calculated position, search the left half of the list
if(arr[pos] > target){
high = pos - 1;
}
else{
// If the target element is greater than the element at the calculated position, search the right half of the list
low = pos + 1;
}
}
return -1;
}
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let target = 5;
let index = interpolation_search(arr, target);
if (index == -1){
console.log(target, " not found in the list");
}
else{
console.log(target, " found at index ", index);
}
// The code is written by Nidhi goel.
输出
在索引 4 处找到 5 个
插值搜索平均进行 log(log(n)) 次比较(如果元素均匀分布),其中 n 是要搜索的元素数量。在最坏的情况下(例如键的数值呈指数增加),它可以进行 O(n) 比较。
时间复杂度: O(log(log n))
空间复杂度: O(1)