插值查找

import java.util.ArrayList;

public class InsertValueSearch {//假设数组从小到大排序

    //递归法,left初始值传入0,right初始值传入array.length - 1
    public static ArrayList<Integer> recurseInsertValueSearch(int[] array, int left, int right, int find) {
        //find < array[left] 和 find > array[right] 必须存在,防止midIndex越界
        if (find < array[left] || find > array[right] || array == null || array.length == 0) {
            return new ArrayList<>();//数组为空或find不存在
        }
        if (array[left] == array[right]) {//针对只有一个元素或只有重复元素
            ArrayList<Integer> indexList = new ArrayList<>();//存放符合find的元素的索引
            addIndex(indexList, left, array, find);//midIndex可以传入left或right
            return indexList;
        }
        int midIndex = left + (right - left) * (find - array[left]) / (array[right] - array[left]);//中间值的索引
        int mid = array[midIndex];//中间值
        if (find > mid) {//find大于中间值,向右递归
            return recurseInsertValueSearch(array, midIndex + 1, right, find);
        } else if (find < mid) {//find小于中间值,向左递归
            return recurseInsertValueSearch(array, left, midIndex - 1, find);
        } else {//find == mid,找到了该值
            ArrayList<Integer> indexList = new ArrayList<>();//存放符合find的元素的索引
            addIndex(indexList, midIndex, array, find);
            return indexList;
        }
    }

    //循环法
    public static ArrayList<Integer> circleInsertValueSearch(int[] array, int find) {
        int left = 0;
        int right = array.length - 1;
        ArrayList<Integer> indexList = new ArrayList<>();//存放符合find的元素的索引
        //find < array[left] 和 find > array[right] 必须存在,防止midIndex越界
        if (array == null || array.length == 0) {
            return indexList;//数组为空
        }
        //不可以用while(left <= right),否则可能在查找不存在的值的时候陷入死循环
        while (find >= array[left] && find <= array[right]) {
            if (array[left] == array[right]) {//针对只有一个元素或大量重复元素
                addIndex(indexList, left, array, find);//midIndex可以传入left或right
                return indexList;
            }
            int midIndex = left + (right - left) * (find - array[left]) / (array[right] - array[left]);//中间值的索引
            int mid = array[midIndex];//中间值
            if (find > mid) {//向右查找
                left = midIndex + 1;
            } else if (find < mid) {//向左查找
                right = midIndex - 1;
            } else {//find == mid,找到了该值
                addIndex(indexList, midIndex, array, find);
                return indexList;
            }
        }
        return indexList;//find不存在
    }

    //封装方法,把等于find的元素的索引加入indexList
    public static void addIndex(ArrayList<Integer> indexList, int midIndex, int[] array, int find) {
        indexList.add(midIndex);//中间值本身的索引放入indexList中
        int temp = midIndex - 1;
        while (true) {//中间值向左寻找相同值的索引
            if (temp < 0 || array[temp] != find) {
                break;
            }
            indexList.add(temp--);
        }
        temp = midIndex + 1;
        while (true) {//中间值向右寻找相同值的索引
            if (temp > array.length - 1 || array[temp] != find) {
                break;
            }
            indexList.add(temp++);
        }
    }
}

 

posted @   半条咸鱼  阅读(15)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示