查找算法

1. 查找算法介绍

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

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

2. 线性查找算法

package com.zx.ds.search;

public class SeqSearch {

    public static int search(int a[],int findVal){
        for(int i=0;i查找算法_第1张图片

注:使用二分查找的前提是该数组是有序的

package com.zx.ds.search;

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

//二分查找该数组必须有序
public class BinarySearch {

    public static int search(int a[],int left,int right,int findVal){

        int mid=(left+right)/2;
        if(left>right){
            return -1;
        }

        if(a[mid]>findVal){
            return search(a,left,mid-1,findVal);
        }else if(a[mid]right){
            return new ArrayList();
        }

        if(a[mid]>findVal){
            return search2(a,left,mid-1,findVal);
        }else if(a[mid] res=new ArrayList<>();
            while(true){
                if(temp<0||a[temp]!=findVal){
                    break;
                }
                res.add(temp);
                temp--;
            }

            res.add(mid);

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

    public static void main(String[] args) {

        int a[]={1,3,4,6,7,8,9};
        int findVal=6;
        int res=search(a,0,a.length-1,findVal);
        if(res==-1){
            System.out.println("not find");
        }else{
            System.out.println("a["+res+"]="+findVal);
        }

        int a2[]={1,2,3,4,4,4,5,5};
        findVal=4;
        List res2=search2(a2,0 , a2.length-1, findVal);
        System.out.println(res2);
        //a[3]=6
        //[3, 4, 5]
       
    }
}

4. 插值查找算法

查找算法_第2张图片

package com.zx.ds.search;

public class InsertSearch {

    //编写插值查找算法
    //说明:插值查找算法,也要求数组是有序的
    public static int search(int a[], int left, int right, int findVal) {

        System.out.println("InsertSearch search()+1..");

        //注意:findVal < arr[0]  和  findVal > arr[arr.length - 1] 必须需要
        //否则我们得到的 mid 可能越界
        if (left > right || findVal > a[a.length - 1] || findVal < a[0]) {
            return -1;
        }

        // 求出mid, 自适应
        int mid = left + (right - left) * (findVal - a[left]) / (a[right] - a[left]);
        if (a[mid] > findVal) {
            return search(a, left, mid - 1, findVal);
        } else if (a[mid] < findVal) {
            return search(a, mid + 1, right, findVal);
        } else {
            return mid;
        }
    }

    public static int binarySearch(int[] arr, int left, int right, int findVal) {
        System.out.println("binarySearch()+1..");
        // 当 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;
        }
    }

    public static void main(String[] args) {

        int a[] = new int[100];
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
        int findVal = 1;
        int res = search(a, 0, a.length - 1, findVal);
        if (res == -1) {
            System.out.println("not find");
        } else {
            System.out.println("a[" + res + "]=" + findVal);
        }

        res = binarySearch(a, 0, a.length - 1, findVal);
        if (res == -1) {
            System.out.println("not find");
        } else {
            System.out.println("a[" + res + "]=" + findVal);
        }

        //以查找1为例,insertSearch优于binarySearch
        //InsertSearch search()+1..
        //a[1]=1
        //binarySearch()+1..
        //binarySearch()+1..
        //binarySearch()+1..
        //binarySearch()+1..
        //binarySearch()+1..
        //binarySearch()+1..
        //binarySearch()+1..
        //a[1]=1
    }
}

插值查找注意事项:
1)对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,速度较快.
2)关键字分布不均匀的情况下,该方法不一定比折半查找要好

你可能感兴趣的:(数据解构&算法)