Estructura de datos Java y algoritmo de búsqueda de algoritmos: [día06]

Algoritmo de búsqueda

Análisis e implementación de búsqueda lineal

Hay una secuencia numérica: {1, 9, -1, 34, 89, 11}, para determinar si el nombre está incluido en la secuencia [Búsqueda secuencial] requiere que si se encuentra, solicitará encontrarlo y dar el valor de subíndice.

public class SeqSearch {
    
    
    public static void main(String[] args) {
    
    
        int arr[] = {
    
    1, 9, -1, 34, 89, 11};//无序数组
        int z = seqSearch(arr, 89);
        if (z == -1){
    
    
            System.out.println("没有找到");
        }else {
    
    
            System.out.println("找到值,下标为" + z);
        }


        int arz[] = {
    
    9,34,11};
        int[] ints = seqzSearch(arr, arz);
        for (int i = 0; i < ints.length; i++) {
    
    
            System.out.print("下标为" +"[" + ints[i] + "]");
        }
    }

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

    public static int[] seqzSearch(int[] arr,int[] arz){
    
    
        int seqz[] = new int[arz.length];

        int index = 0;
        for (int i = 0; i < arr.length; i++) {
    
    
            for (int j = 0; j < arz.length; j++) {
    
    
                if (arr[i] == arz[j]){
    
    
                    seqz[index] = i;
                    index++;
                }
            }

        }
        return seqz;
    }

}


Análisis y realización de búsquedas binarias

Realice una búsqueda binaria en una matriz ordenada {1,8, 10, 89, 1000, 1234}, ingrese un número para ver si este número existe en la matriz y busque el subíndice; de ​​lo contrario, aparecerá el mensaje "no existe tal número". .

Análisis de la idea de búsqueda binaria:

  1. Primero determine el subíndice en el medio de la matriz mid = (left + right) / 2

  2. Luego compare
    findVal con arr [mid] para encontrar el número que desea encontrar 2.1 findVal> arr [mid], significa que el número que desea encontrar está en el lado derecho de mid, por lo que necesita buscar a la derecha de forma recursiva.
    2.2 findVal <arr [mid], significa que el número que desea encontrar está a la izquierda de mid, por lo que debe buscarlo de forma recursiva a la izquierda.
    2.3 findVal == arr [mid] Si lo encuentra, regrese.

¿Cuándo debemos finalizar la recursividad?

  • Finalice la recursividad cuando se encuentre.
  • Toda la matriz es recursiva, pero findVal aún no se encuentra, y la recursividad debe finalizar cuando left> right.

Código

//注意:使用二分查找的前提是 该数组是有序的。
public class BinarySearch {
    
    
    public static void main(String[] args) {
    
    
        int arr[] = {
    
    1, 8, 10, 88, 1000, 1234};

        int resIndex = binarySearch(arr, 0, arr.length, 88);
        System.out.println("resIndex=" + resIndex);


    }

    //二分查找算法

    /**
     *
     * @param arr   数组
     * @param left  查找时左边的索引
     * @param right 右边的索引
     * @param findVal   要查找的值
     * @return 如果找到就返回下标, 如果没有找到, 就返回-1
     */
    public static int binarySearch(int[] arr, int left, int right, int findVal) {
    
    

        //当left > right 时,说明递归整个数组,但是没有找到
        if (left > right){
    
    
            return -1;
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) {
    
     //向 右递归
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
    
     //向 左递归
            return binarySearch(arr, left, mid - 1, findVal);
        }else {
    
    
            return mid;
        }
    }
}

Optimización de algoritmos

//注意:使用二分查找的前提是 该数组是有序的。
public class BinarySearch {
    
    
    public static void main(String[] args) {
    
    
        int arr[] = {
    
    1, 8, 10, 88, 1000, 1000, 1000, 1000, 1234,1234,6666,6666};

        List<Integer> list = binarySearchz(arr, 0,arr.length - 1, 6666);
        System.out.println(list);


    }

    //二分查找算法

    /**
     *
     * @param arr   数组
     * @param left  查找时左边的索引
     * @param right 右边的索引
     * @param findVal   要查找的值
     * @return 如果找到就返回下标, 如果没有找到, 就返回-1
     */
    public static int binarySearch(int[] arr, int left, int right, int findVal) {
    
    

        //当left > right 时,说明递归整个数组,但是没有找到
        if (left > right){
    
    
            return -1;
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) {
    
     //向 右递归
            return binarySearch(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
    
     //向 左递归
            return binarySearch(arr, left, mid - 1, findVal);
        } else {
    
    
            return mid;
        }
    }

    //思考题
    /*
    题:{1,8,10,89,1000,1000,1234}当一个有序数组中,有多个相同的数值时
    如何将所有的数值都查找到,比如这里的1000

    思路分析:
    1.在找到mid 索引值时,不要马上返回
    2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
    3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
    4.将ArrayList返回
     */

    public static List<Integer> binarySearchz(int[] arr, int left, int right, int findVal) {
    
    



        //当left > right 时,说明递归整个数组,但是没有找到
        if (left > right){
    
    
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if (findVal > midVal) {
    
     //向 右递归
            return   binarySearchz(arr, mid + 1, right, findVal);
        } else if (findVal < midVal) {
    
     //向 左递归
            return binarySearchz(arr, left, mid - 1, findVal);
        } else {
    
    

            /*思路分析:
            1.在找到mid 索引值时,不要马上返回
            2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
            3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
            4.将ArrayList返回*/
            List<Integer> resIndexlist = new ArrayList<Integer>();
            //2.向mid 索引值得左边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
            int temp = mid - 1;
            while (true){
    
    
                if (temp < 0 || arr[temp] != findVal){
    
    //退出
                    break;
                }
                //否则,就把temp 放入到集合resIndexlist中
                resIndexlist.add(temp);
                temp -= 1;//temp左移
            }
            resIndexlist.add(mid);
            //3.向mid 索引值的右边扫描,将所有满足 1000的元素下标,加入到集合ArrayList
            temp = mid + 1;
            while (true){
    
    
                if (temp > arr.length -1 || arr[temp] != findVal){
    
    //退出
                    break;
                }
                //否则,就把temp 放入到集合resIndexlist中
                resIndexlist.add(temp);
                temp += 1;//temp左移

            }
        //    resIndexlist.add(mid);//别忘了把之前找到的放进去
            return resIndexlist;
        }
    }
}

Análisis e implementación de búsqueda por interpolación

Principio de búsqueda de interpolación

  • El algoritmo de búsqueda de interpolación es similar a la búsqueda binaria, la diferencia es que la búsqueda de interpolación comienza desde el medio adaptativo cada vez.

  • La fórmula para encontrar el índice medio en la mitad de la búsqueda, bajo representa el índice izquierdo a la izquierda, alto representa el índice derecho a la derecha. La clave
    es el valor de búsqueda del que hablamos anteriormente.

Inserte la descripción de la imagen aquí

int mid = low + (alto - bajo) * (clave - arr [bajo]) / (arr [alto] -
arr [bajo]); / 插值 索引 /

Correspondiente a la fórmula del código anterior:

int mid = left + (derecha - izquierda) * (findVal - arr [izquierda]) / (arr [derecha]
- arr [izquierda])


Ilustre el algoritmo de búsqueda de interpolación 1-100

Ideas específicas:

Array arr = [1, 2, 3,…, 100]

  • Si necesitamos encontrar el valor 1

  • Usando la búsqueda binaria, necesitamos recurrir varias veces para encontrar 1

  • Utilice el algoritmo de búsqueda de interpolación: int mid = left + (right - left) * (findVal - arr [left]) / (arr [right] - arr [left])

  • int mid = 0 + (99 - 0) * (1 - 1) / (100 - 1) = 0 + 99 * 0/99 = 0

  • Por ejemplo, el valor que buscamos es 100

  • int mid = 0 + (99 - 0) * (100 - 1) / (100 - 1) = 0 + 99 * 99/99 = 0

  • 99 = 99

En resumen, algoritmo de búsqueda de interpolación -> conjunto de cálculos de fórmulas

Supongo que te gusta

Origin blog.csdn.net/SwaeLeeUknow/article/details/108738029
Recomendado
Clasificación