四种基本的查找算法

  • 时间:
  • 浏览:
  • 来源:互联网

1、顺序(线性)查找

1.1、实现思路

image-20210320145647188

1.2、实现代码

public class Demo1 {
    public static void main(String[] args) {
        int [] arr={1,9,5,2,8,4,3};
        int i = seqSearch(arr, 3);
        if (i==-1){
            System.out.println("没有查找到要查找的值");
        }else {
            System.out.println(i);
        }

    }

    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、二分查找/折半查找

2.1、实现思路

要求是有序数组

image-20210320151537827

2.2、实现代码

public class Demo2 {
    public static void main(String[] args) {
            int [] arr={1,2,3,4,5,6,7,8,9};
        System.out.println(binarySearch(arr, 0, arr.length-1, 66));
    }

    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 midValue = arr[mid];
        if (findVal>midValue){//向右递归
            return binarySearch(arr,mid+1,right,findVal);
        }else if (findVal>midValue){
            return binarySearch(arr,left,mid-1,findVal);
        }else {
            return mid;
        }
    }
}

2.3、升级代码实现

//当有多个重复值的时候,返回所有符合的集合
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal ){
        //当left大于right,说明递归整个数组,但是没有找到
        if (left>right){
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;
        int midValue = arr[mid];
        if (findVal>midValue){//向右递归
            return binarySearch2(arr,mid+1,right,findVal);
        }else if (findVal>midValue){
            return binarySearch2(arr,left,mid-1,findVal);
        }else {
            ArrayList<Integer> resIndexList = new ArrayList<>();
            int temp=mid-1;
            while (true){
                if (temp<0||arr[temp] !=findVal){
                    break;
                }
                resIndexList.add(temp);
                --temp;
            }
            resIndexList.add(mid);

           temp=mid+1;
            while (true){
                if (temp>arr.length-1||arr[temp] !=findVal){
                    break;
                }
                resIndexList.add(temp);
                ++temp;
            }
            return resIndexList;
        }

    }

3、插值查找

3.1、实现思路

当数据连续,插值算法优越性好

image-20210320160512094

image-20210320160437239

image-20210320162356728

3.2、实现代码

//公式
int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);

public class Demo3 {
    public static void main(String[] args) {
        int[] arr = new int[100];
        for (int i = 0; i < 100; i++) {
            arr[i] = i + 1;
        }
        System.out.println(insertValueSearch(arr, 0, arr.length - 1, 1));
    }

    public static int insertValueSearch(int[] arr, int left, int right, int findVal) {
        if (left > right || findVal < arr[0] || findVal > arr[arr.length - 1]) {
            return -1;
        }
        int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
        int midVal =arr[mid];

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

4、斐波那契(黄金分割法)查找

4.1、实现思路

image-20210320165446284

4.2、实现代码

public class Demo4 {
    public static int maxSize = 20;

    public static void main(String[] args) {
        int[] arr = new int[]{1, 8, 10, 89, 1000, 1234};
        System.out.println("index=" + fibSearch(arr, 89));
    }

    public static int[] fib() {
        int[] f = new int[maxSize];
        f[0] = 1;
        f[1] = 1;

        for (int i = 2; i < maxSize; ++i) {
            f[i] = f[i - 1] + f[i - 2];
        }

        return f;
    }

    public static int fibSearch(int[] a, int key) {
        int low = 0;
        int high = a.length - 1;
        int k = 0;
        int mid = 0;

        int[] f;
        for (f = fib(); high > f[k] - 1; ++k) {
        }

        int[] temp = Arrays.copyOf(a, f[k]);

        for (int i = high + 1; i < temp.length; ++i) {
            temp[i] = a[high];
        }

        while (low <= high) {
            mid = low + f[k - 1] - 1;
            if (key < temp[mid]) {
                high = mid - 1;
                --k;
            } else {
                if (key <= temp[mid]) {
                    if (mid <= high) {
                        return mid;
                    }

                    return high;
                }

                low = mid + 1;
                k -= 2;
            }
        }

        return -1;
    }
}
//注意,放mid大的时候,此时返回的值为high
//反之,返回值为mid
       }

                return high;
            }

            low = mid + 1;
            k -= 2;
        }
    }

    return -1;
}

}
//注意,放mid大的时候,此时返回的值为high
//反之,返回值为mid


本文链接http://www.dzjqx.cn/news/show-617006.html