查找(线性查找、二分查找、插值查找)

一、线性查找

线性查找就好比去停车场(一排)找一个车牌号对应车的位置,只能一个一个遍历呗。


public class SeqSearch {
    @Test
    public void test(){

        int[] arr = {1,8,3,9,10,7};
        int value = 5;
        if ( SeqSearch.seqSearch(arr,value) == -1) {
            System.out.println("没找到");
        }else {
            System.out.println(SeqSearch.seqSearch(arr,value));
        }
    }

    /**
     * 线性查找,直接暴力遍历数组
     * @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;
    }
}

二、二分查找

package com.sgh.algorithm4.search;

import com.sgh.algorithm4.algorithmdatastructure.sort.BubbleSort;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/6/9 0009 20:49
 */
public class BinarySearch {

    @Test
    public void test() {
        BinarySearch binarySearch = new BinarySearch();
        int[] arr = {2, 6, 10, 11, 23, 44, 45};
        BubbleSort.bubbleSort(arr);
//        int i = binarySearch.searchRecursion(arr, 0, arr.length-1, 44);
//        int j = binarySearch.searchRecursion2(arr, 0, arr.length-1, 44);
//        System.out.println(i);
//        System.out.println(j);
        //通过while循环来实现
        int i1 = binarySearch.searchByWhile(arr, 7);
        System.out.println(i1);

        int[] arrAll = {2, 3, 4, 4, 4, 4, 6, 7, 8};
        System.out.println(binarySearch.searchRecursionAll(arrAll, 0, arr.length - 1, 4));
    }


    /**
     * 二分查找 优化(查询列表中的所有值)
     * @param arr       被查询对象
     * @param leftFlag  左索引
     * @param rightFlag 右索引
     * @param value     要查询的值
     * @return 返回被查询值的索引
     */
    public List<Integer> searchRecursionAll(int[] arr, int leftFlag, int rightFlag, int value) {
        if (leftFlag > rightFlag) {
            return null;
        }
        int middleFlag = (rightFlag + leftFlag) / 2;
        int middleValue = arr[middleFlag];
        if (value < middleValue) {
            return searchRecursionAll(arr, leftFlag, rightFlag - middleFlag - 1, value);
        } else if (value > middleValue) {
            return searchRecursionAll(arr, leftFlag + middleFlag + 1, rightFlag, value);
        } else {
            //如果找到了不急于返回
            List<Integer> flagList = new ArrayList<Integer>();
            int temp = middleFlag - 1;
            while (true) {
                if (temp < 0 || arr[temp] < middleValue) {
                    break;
                }
                flagList.add(temp--);
            }
            flagList.add(middleFlag);
            temp = middleFlag + 1;
            while (true) {
                if (temp > arr.length -1 || arr[temp] > middleValue) {
                    break;
                }
                flagList.add(temp++);
            }
            return flagList;
        }
    }

    /**
     * 二分查找 递归 查询到一个
     * 将数组一半一半进行减少
     * @param arr       被查询对象
     * @param leftFlag  左索引
     * @param rightFlag 右索引
     * @param value     要查询的值
     * @return 返回被查询值的索引
     */
    public int searchRecursion(int[] arr, int leftFlag, int rightFlag, int value) {
        if (leftFlag > rightFlag) {
            return -1;
        }
        int middleFlag = (rightFlag + leftFlag) / 2;
        int middleValue = arr[middleFlag];
        if (value < middleValue) {
            return searchRecursion(arr, leftFlag, rightFlag - middleFlag - 1, value);
        } else if (value > middleValue) {
            return searchRecursion(arr, leftFlag + middleFlag + 1, rightFlag, value);
        } else {
            return middleFlag;
        }
    }

    /**
     * 二分查找 递归 查询到一个
     *
     * @param arr       被查询对象
     * @param leftFlag  左索引
     * @param rightFlag 右索引
     * @param value     要查询的值
     * @return 返回被查询值的索引
     */
    public int searchRecursion2(int[] arr, int leftFlag, int rightFlag, int value) {
        if (leftFlag > rightFlag) {
            return -1;
        }
        int middleFlag = (rightFlag + leftFlag) / 2;
        int middleValue = arr[middleFlag];
        if (value < middleValue) {
            return searchRecursion2(arr, leftFlag, middleFlag - 1, value);
        } else if (value > middleValue) {
            return searchRecursion2(arr, middleFlag + 1, rightFlag, value);
        } else {
            return middleFlag;
        }
    }

    /**
     * 用while循环实现二分查找
     * @param arr
     * @param value
     * @return
     */
    public int searchByWhile(int[] arr, int value) {
        boolean flag = true;
        int middleFlag = arr.length / 2;
        int middleValue = arr[middleFlag];
        int leftFlag = 0;
        int rightFlag = arr.length - 1;
        int result = -1;
        while (flag) {
            if (leftFlag > rightFlag) {
                flag = false;
            } else if (value < middleValue) {
                rightFlag = (middleFlag - 1);
                middleFlag = (rightFlag + leftFlag) / 2;
                middleValue = arr[middleFlag];
            } else if (value > middleValue) {
                leftFlag = (middleFlag + 1);
                middleFlag = (rightFlag + leftFlag) / 2;
                middleValue = arr[middleFlag];
            } else if (value == middleValue) {
                result = middleFlag;
                flag = false;
            }
        }
        return result;
    }
}

三、插值查找

package com.sgh.algorithm4.search;

import org.junit.Test;

/**
 * 插值查找 算法
 * @author sugha
 * @version 1.0
 * @description
 * @date 2021/6/10 0010 14:10
 */
public class InsertValueSearch {
    @Test
    public void test1() {
        InsertValueSearch insertValueSearch = new InsertValueSearch();
        int[] arr = new int[100];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i +1;
        }
//        int[] arr = {2, 6, 10, 11, 23, 44, 45};
        System.out.println(insertValueSearch.insertValueSearch(arr, 0, arr.length - 1,10 ));

        System.out.println(insertValueSearch.searchRecursion(arr, 0, arr.length - 1, 10));
    }

    public int insertValueSearch(int[] arr , int leftFlag ,int rightFlag , int findValue) {
        System.out.println("hello");
        if (leftFlag > rightFlag) {
            return -1;
        }
//        int middleFlag = leftFlag + (((findValue - arr[leftFlag]) / (arr[rightFlag] - arr[leftFlag])) * (rightFlag - leftFlag));
        int middleFlag = leftFlag + (findValue - arr[leftFlag]) * (rightFlag - leftFlag) / (arr[rightFlag] - arr[leftFlag]);
        if (arr[middleFlag] == findValue) {
            return middleFlag;
        }else if (arr[middleFlag] < findValue) {
            return insertValueSearch(arr , middleFlag + 1,rightFlag,findValue);
        }else if (arr[middleFlag] > findValue) {
            return insertValueSearch(arr , leftFlag,middleFlag - 1,findValue);
        }else {
            return -1;
        }

    }


    /**
     * 二分查找 递归 查询到一个
     * 将数组一半一半进行减少
     * @param arr       被查询对象
     * @param leftFlag  左索引
     * @param rightFlag 右索引
     * @param value     要查询的值
     * @return 返回被查询值的索引
     */
    public int searchRecursion(int[] arr, int leftFlag, int rightFlag, int value) {
        System.out.println("hello");
        if (leftFlag > rightFlag) {
            return -1;
        }
        int middleFlag = (rightFlag + leftFlag) / 2;
        int middleValue = arr[middleFlag];
        if (value < middleValue) {
            return searchRecursion(arr, leftFlag,  middleFlag - 1, value);
        } else if (value > middleValue) {
            return searchRecursion(arr, middleFlag + 1, rightFlag, value);
        } else {
            return middleFlag;
        }
    }
}

你可能感兴趣的:(算法与数据结构,java,算法)