[java] - Algorithms and Data Structures - Chapter 8 - Search Algorithms

Eight, search algorithm

1. Sequential (linear) search algorithm

    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. Binary search

1) Analysis of train of thought

  1. First determine the subscript in the middle of the array

    mid= (left+right)/2

  2. Then compare the number findval that needs to be found with arr[mid]

    • findval > arr[mid], indicating that the number you want to find is on the right side of mid, so you need to recursively find 2.2 to the right
    • findyal<arr[mid], indicating that the number you want to find is on the left of mid, so you need to recursively find 2.3 to the left
    • findval == arr[mid] means found, then return
  3. / when we need to end the recursion

    • end recursion when found
    • Recursively complete the entire array, still did not find findval, and also need to end the recursion when left > right and need to exit

2) Code implementation

    // 递归
    public static int binarySearch(int arr[], int min, int max, int findVal) {
    
    
        if (min > max) {
    
    
            return -1;
        }
        int mid = (min + max) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) {
    
     // 向右
            return binarySearch(arr, mid + 1, max, findVal);
        } else if (findVal < midVal) {
    
    
            return binarySearch(arr, min, mid - 1, findVal);
        } else {
    
    
            return mid;
        }
    }
    
    // 不用递归
        // 循环
    public static int binarySearch2(int arr[], int findVal) {
    
    

        int min = 0;
        int max = arr.length - 1;
        while (true) {
    
    
            int mid = (max + min) / 2;
            if (findVal == arr[mid]) {
    
    
                return mid;
            } else if (findVal > arr[mid]) {
    
    
                min = mid;
            } else {
    
    
                max = mid;
            }
        }
    }

3. Interpolation search algorithm

1) Principle introduction

insert image description here

2) Code

  • the code
public static int insertSearch(int[] arr, int findValue) {
    
    
        int min = 0;
        int max = arr.length - 1;
        int count = 0;
        int mid = 0;
        while (true) {
    
    
            count++;

            mid =  min +  (max - min) * (findValue - arr[min]) / (arr[max] - arr[min]);
            if (min > max || findValue < arr[0] || findValue > arr[arr.length - 1]) {
    
    
                break;
            }
            if (arr[mid] == findValue) {
    
    
               break;
            }
            if (arr[mid] > findValue) {
    
    
                min = mid + 1;
            }
            if (arr[mid] < findValue) {
    
    
                max = mid - 1;
            }
        }
        System.out.println(count);
        return mid;
    }

4. Fibonacci (Golden Section)

1 Introduction

  1. The golden section point refers to dividing a line segment into two parts, so that the ratio of one part to the total length of the base is equal to the ratio of the other part to this part. A close approximation to its first three digits is 0.618. Because the shape designed according to this ratio is very beautiful, it is called the golden section, also known as the ratio of China and foreign countries. It's a magic number that can have unintended effects.
    2. The Fibonacci sequence {1,1,2,3,5,8,13,21,34,55}, the ratio of two adjacent numbers in the Fibonacci sequence, is infinitely close to 0.618

2) Principle

The Fibonacci search principle is similar to the first two, only the position of the middle node (mid) is changed, mid is no longer obtained from the middle or interpolation, but is located near the golden section point,

That is, mid=low+F(k-1)-1 (F represents the Fibonacci sequence)

insert image description here

  1. From the properties of the Fibonacci sequence F[K]=F[k-1]+F[k-2], we can get (F[k]-1)=(F[k-1]-1)+( F[k-2]-1)+1.

    The formula shows that as long as the length of the sequence table is F[k]-1, the table can be divided into two sections whose length is F[k-]-1 and F[k-2]-1,

    That is, as shown in the figure above. Thus the middle position is mid=low+F(k-1)-1

  2. Similarly, each subsection can be split in the same way

  3. However, the length n of the sequence table is not necessarily exactly equal to F[K]-1, so it is necessary to increase the length n of the original sequence table to F[K-1]. As long as the k value here can make F[k]-1 just greater than or equal to n, it can be obtained from the following code. After the length of the sequence table increases, the newly added position is from n+1 to F[k]-1), All can be assigned to the value of n position.

3) Code

public class 斐波那契查找 {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 8, 10, 89, 1000, 1234};
        System.out.println(fibSearch(arr, 89));
    }

    // 获取一个斐波那契数列
    public static int[] fib() {
    
    
        int[] f = new int[20];
        f[0] = 1;
        f[1] = 1;
        for (int i = 2; i < f.length; i++) {
    
    
            f[i] = f[i - 1] + f[i - 2];
        }
        return f;
    }

     public static int fibSearch(int[] arr, int key) {
    
    
        //数组左侧索引
        int low = 0;
        //数组右侧索引
        int high = arr.length - 1;
        //比右侧索引大的第一个斐波那契数对应的索引
        int k = 0;
        //黄金分割点
        int mid = 0;
        //斐波那契数列
        int[] f = fib();
        //由数组最大值计算k
        while (high > f[k] - 1) {
    
    
            k++;
        }

        //因为f[k]的值可能大于数组的长度,因此需要给原数组扩容到长度 == f(k)
        int[] tmp = Arrays.copyOf(arr, f[k]);
        //调用copyOf方法后在扩容部分全部补了0,实际上需要补数组的最后一位
        for (int i = high + 1; i < tmp.length; i++) {
    
    
            tmp[i] = arr[high];
        }
        //使用while循环来查找需要找的数
        while (low <= high) {
    
    
            //先计算黄金分割点
            mid = low + f[k - 1] - 1;
            //判断黄金分割点的元素和要查找的元素的关系
            //如果要查找的值在mid左边,重置high和k
            if (tmp[mid] > key){
    
    
                high = mid - 1;
                k--;
                //如果要查找的值在mid右边
            }else if (tmp[mid] < key){
    
    
                low = mid + 1;
                k -= 2;
                //否则找到该元素
            }else {
    
    
                if (mid <= high){
    
    
                    return mid;
                }else {
    
    
                    return high;
                }
            }
        }
        //如果循环结束后还没有找到,说明没有
        return -1;
     }

Guess you like

Origin blog.csdn.net/m0_56186460/article/details/124481721