查找算法总结:线性查找、二分查找、插值查找

查找算法介绍

在 java 中,我们常用的查找有四种:

1) 顺序(线性)查找
2) 二分查找/折半查找
3) 插值查找
4) 斐波那契查找


1、线性查找算法

有一个数列: {1,8, 10, 89, 1000, 1234} ,判断数列中是否包含此名称【顺序查找】 要求: 如果找到了,就提 示找到,并给出下标值

 /*** 这里我们实现的线性查找是找到一个满足条件的值,就返回*/
    public static int seqSearch(int[] arr, int value) {
        // 线性查找是逐一比对,发现有相同值,就返回下标 
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == value) {
                return i; }
        }
        return -1;
    }

2、二分查找:

在这里插入图片描述

   private static void lookUp() {
        // 二分查找
        int arr[] = { 1, 8, 10, 89,1000,1000, 1234 };
        int num = BinarySearch(arr, 1000);
        System.out.println(num);
    }
  /**
     * 二分查找
     * @param arr
     * @param value
     * @return
     */
    private static int BinarySearch(int[] arr, int value) {
        // 最小索引
        int min = 0;
        // 最大索引
        int max = arr.length - 1;
        // 中间值
        int middle = (max + min) / 2;


        while (min <= max){
            if(value > arr[middle]) {
                min = middle + 1;
            }else if(value < arr[middle]) {
                max = middle - 1;
            }else if(arr[middle] == value) {
                // 如果数组中有多个相同的数据,怎么都找到
                moreNum(arr, value, middle);

                return middle;
            }
            middle = (min + max) / 2;
        }
        return - 1;

    }
  /**
     * 多个数据
     */
    private static void moreNum(int[] arr, int value, int middle) {
        /**
         *  * 思路分析
         *  // * 1. 在找到 mid 索引值,不要马上返回
         *  // * 2. 向 mid 索引值的左边扫描,将所有满足 value = 1000, 的元素的下标,加入到集合 ArrayList
         *  // * 3. 向 mid 索引值的右边扫描,将所有满足value = 1000, 的元素的下标,加入到集合 ArrayList
         *  // * 4. 将 Arraylist 返回
          */

        // 如果数组中有多个相同的数据,怎么都找到
        ArrayList list = new ArrayList();
        list.add(middle);
        // 向左查找
        int cur = middle - 1;
        while (true){
            // 下标要大于0,  因为二分查找都是有序的,如果相邻的这个不是要找的值,直接break 跳出
            if(cur < 0 || arr[cur] != value ) {
                break;
            }
            list.add(cur);
            // 左移
            cur -=1;
        }

        // 向右边查找
        cur = middle + 1;
        while (true){
            if(cur > arr.length - 1 || arr[cur] != value) {
                break;
            }
            list.add(middle);
            middle += 1;
        }

        for(int i = 0; i < list.size(); i++) {
            //打印结果:
               //  一共有2    :5
   			   //  一共有2    :4
            System.out.println("一共有" + list.size() + "    :"+  list.get(i));
        }
        
    }

3、插值查找

1)插值查找原理介绍

插值查找算法类似于二分查找,不同的是插值查找每次从自适应 mid 处开始查找。

2)将折半查找中的求 mid 索引的公式 , low 表示左边索引 left, high 表示右边索引 right. key 就是前面我们讲的 findVal

在这里插入图片描述

3) int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;/插值索引/

对应前面的代码公式:
int mid = left + (right – left) * (findVal – arr[left]) / (arr[right] – arr[left])

4)举例说明插值查找算法 1-100 的数组

在这里插入图片描述

代码实现

private static void lookUp() {
    // 插值查找
    int arr[] = { 1, 8, 10, 89,1000,1000, 1234};
    int findVal = 1234;
    int postion = insertSearch(arr, findVal);
    System.out.println(postion);
}
    
// arr 有序的数组
private static int insertSearch(int[] arr, int findVal) {
    int left = arr[0];
    int right = arr.length - 1;
    // 坐标下标不能超过右边下标,  查找的值必须是  大于等于 最小值 兵器小于等于最大只
    while (left <= right && findVal >= arr[left] && findVal <= arr[right]){
        // 自适应mid
        int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
        int midVal = arr[mid];
        if(findVal > midVal) {
            left = mid + 1;
        }else if(findVal < midVal) {
            right = mid - 1;
        }else {
            return mid;
        }
    }
    return -1;
}
发布了51 篇原创文章 · 获赞 78 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_39079048/article/details/103644122