插值查找算法介绍

在这里插入图片描述
对应前面的代码公式:mid = left + (indValue - arr[right])/(arr[right]-arr[left])*(right-left)
一步定位

代码实现

package com.search;

import java.util.Arrays;

public class InsertValueSearch {
    public static void main(String[] args) {
//        int[] arr= new int[100];
//        for (int i=0;i<100;i++) {
//            arr[i]=i+1;
//        }
        int[] arr = {1,8,10,89,1000,1234};
        int i = insertValueSearch(arr, 0, arr.length - 1, 1234);
        System.out.println(i);

    }

    //编写插值查找算法
    //插值查找算法,也要求数组是有序的
    /**
     *
     * @param arr  数组
     * @param left  左边索引
     * @param right   右边索引
     * @param findValue  查找的值
     * @return  如果找到就返回对应的下标
     */
    public static int insertValueSearch(int[] arr,int left,int right,int findValue){
        System.out.println("我被调用了--");
        // findValue<arr[0]和findValue>arr[99]是必须需要的,否则我们得到的mid的值可能越界
        if (left>right || findValue<arr[0] || findValue>arr[arr.length-1]){
            return -1;
        }
        int mid = left + (right-left)*(findValue-arr[left])/(arr[right]-arr[left]);
        int midVal = arr[mid];
        if (findValue>midVal){//说明向右边递归
            return insertValueSearch(arr,mid+1,right,findValue);
        }else if (findValue<midVal){//向左递归查找
            return insertValueSearch(arr,left,mid-1,findValue);
        }else {
            return mid;
        }
    }

}

注意事项

1、对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快。
2、关键字分布不均匀的情况下,该方法不一定比折半查找要好。

### 插值查找算法的工作原理 插值查找是一种基于二分查找改进的高效查找算法,适用于有序数组。它通过计算目标值可能存在的位置来动态调整中间点 `mid` 的选取方式,从而减少不必要的比较次数并提升性能。 #### 工作原理概述 插值查找的核心思想是利用公式估算目标值在数组中的具体位置,而不是像传统二分查找那样固定取中间元素作为比较对象。这种方法能够显著缩短搜索路径长度,特别是在数据分布较为均匀的情况下效果尤为明显[^1]。 #### 计算中间索引的公式 为了确定新的中间点 `mid`,插值查找采用如下公式: ```python mid = low + (high - low) * (key - arr[low]) // (arr[high] - arr[low]) ``` 其中: - `low` 是当前子数组左边界索引; - `high` 是当前子数组右边界索引; - `key` 是待查找的目标值; - `arr[low]` 和 `arr[high]` 分别代表数组两端的数值。 此公式的推导依据于假设输入序列近似呈现线性关系,因此可以根据比例关系预测目标值的大致位置[^2]。 #### 算法实现步骤 以下是插值查找的一个典型 Python 实现: ```python def interpolation_search(arr, key): low = 0 high = len(arr) - 1 while low <= high and key >= arr[low] and key <= arr[high]: if arr[high] == arr[low] or arr[low] == key: break # 使用插值公式计算 mid pos = int(low + ((float(high - low) / (arr[high] - arr[low])) * (key - arr[low]))) # 如果找到则返回下标 if arr[pos] == key: return pos # 调整区间继续寻找 elif arr[pos] < key: low = pos + 1 else: high = pos - 1 return -1 # 查找不到时返回 -1 表示失败 ``` 上述代码展示了如何运用插值公式逐步缩小候选区域直至定位到目标项或者确认不存在该值为止[^3]。 #### 性能分析 相比普通的二分查找,当处理大规模且分布相对平均的数据集时,插值查找通常表现出更好的时间复杂度O(log log n),这是因为每次迭代都能更加精准地接近实际匹配点。然而,在极端情况下(比如高度偏斜的数据),它的表现可能会退化至最差情况下的 O(n)[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值