算法与数据结构-06-插值查询
插值查询
二分查找虽然快捷,但是每次折半查找,查找过程不具有动态性,究其原因是由于待查找元素每次与mid中间值进行比较,但中间值的获取算法是固定的,即(left+right)/ 2 ,如果获取中间值得算法是动态的或许会更高效,这就是插值查询。
package day05; import java.util.Arrays; /** * 二分查找进阶【插值查找】 * 插值寻找公式:int mid=left+(right-left)*(findVal-arr[left])/(arr[right]-arr[left]) */ public class InterpolationSearch { private static int binarySearchNumber = 0; private static int interpolationSearchNumber = 0; public static void main(String[] args) { int[] array = new int[100]; for (int i = 0; i < array.length; i++) { array[i] = i; } // System.out.println(Arrays.toString(array)); // 测试二分查找 查找99需要递归多少次 int binarySearchIndex = binarySearch(99, 0, array.length-1, array); System.out.println(binarySearchIndex); System.out.println("--------------------------------------------"); // 测试插值查找 查找99需要递归多少次 int interpolationSearchIndex = interpolationSearch(99, 0, array.length-1, array); System.out.println(interpolationSearchIndex); } /** * 插值查找 * 使用条件:数组数据有序,数据相对连续 * * @param findVal * @param left * @param right * @param arr * @return */ public static int interpolationSearch(int findVal, int left, int right, int[] arr) { System.out.println("插值查询 查找" + findVal + "递归" + (++interpolationSearchNumber) + "次~"); if (left > right || findVal < arr[left] || findVal > arr[right]) { return -1; } int mid = left + (right - left) * ((findVal - arr[left]) / (arr[right] - arr[left])); int midVal = arr[mid]; if (findVal < midVal) { right = mid - 1; return interpolationSearch(findVal, left, right, arr); } else if (findVal > midVal) { left = mid + 1; return interpolationSearch(findVal, left, right, arr); } else { return mid; } } /** * 二分查找 * 适应条件:数组有序 * * @param findVal * @param left * @param right * @param arr * @return */ public static int binarySearch(int findVal, int left, int right, int[] arr) { System.out.println("二分查询 查找" + findVal + "递归" + (++binarySearchNumber) + "次~"); if (left > right || findVal < arr[left] || findVal > arr[right]) { return -1; } // int mid = left + (1/2)*(right - left) ; int mid = left + (right - left) / 2; // int mid = (left+right)/2; int midVal = arr[mid]; if (findVal < midVal) { right = mid - 1; return binarySearch(findVal, left, right, arr); } else if (findVal > midVal) { left = mid + 1; return binarySearch(findVal, left, right, arr); } else { return mid; } } }结论:经过对比 查询99 二分法需要六次递归,而插值查询只需要一次。 但是插值查询的效率不一定比二分查找效率高。如果数组元素跳跃性大,不够连续,会出现插值查询效率比二分查找效率低的情况发生。
注意:插值查询和二分查找最大的区别就是获取"中间值"的算法不同!!!
分类:
[基础] 算法与数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~