java常用查找算法

java常用查找算法

线性查找

/**
 * 找到一个就返回
 * @param arr   数组
 * @param value 需要找的数
 * @return      找的数的下标,没找到为-1
 */
public static int seqSearch(int[] arr, int value) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == value) {
            return i;
        }
    }
    return -1;
}

二分查找


递归法(找一个)

/**
     * 二分查找一个值
     * 必须left和right中间有序
     *
     * @param arr   数组
     * @param left  左边的索引
     * @param right 右边的索引
     * @param value 需要查找的值
     * @return 值的下标,-1为找不到
     */
    public static int binary(int[] arr, int left, int right, int value) {

        if (left > right) {
            return -1;
        }

        int mid = left + (right - left) / 2;
        int midValue = arr[mid];

        // 如果要找的值在右边
        if (value > midValue) {
            // 向右递归
            return binary(arr, mid + 1, right, value);
        } else if (value < midValue) {
            return binary(arr, left, mid - 1, value);
        } else {
            // 等于,返回
            return mid;
        }
    }

递归法(找多个)

/**
 * 二分查找多个值
 * 必须left和right中间有序
 *
 * @param arr   数组
 * @param left  左边的索引
 * @param right 右边的索引
 * @param value 需要查找的值
 * @return 值的下标, null为找不到
 */
public static List binary02(int[] arr, int left, int right, int value) {

    if (left > right) {
        return null;
    }

    int mid = left + (right - left) / 2;
    int midValue = arr[mid];

    // 如果要找的值在右边
    if (value > midValue) {
        // 向右递归
        return binary02(arr, mid + 1, right, value);
    } else if (value < midValue) {
        return binary02(arr, left, mid - 1, value);
    } else {
        List<Integer> ans = new ArrayList<>();
        int temp = mid - 1;

        // 向左扫描
        while (true) {
            if (temp < 0 || arr[temp] != value) {
                break;
            }
            ans.add(temp--);
        }
        ans.add(mid);

        // 向右扫描
        temp = mid + 1;
        while (true) {
            if (temp > arr.length - 1 || arr[temp] != value) {
                break;
            }
            ans.add(temp++);
        }

        return ans;
    }
}

插值查找

public static int insert(int[] arr, int left, int right, int value) {
        if (left > right || value < arr[0] || value > arr[arr.length - 1]) {
            return -1;
        }

        int mid = left + (right - left) * ((value - arr[left]) / (arr[right] - arr[left]));
        int midValue = arr[mid];

        if (value > midValue) {
            // 在mid的右边
            return insert(arr, mid + 1, right, value);
        } else if (value < midValue) {
            // 在mid的左边
            return insert(arr, left, mid - 1, value);
        } else {
            return mid;
        }
    }

斐波那契黄金分割法查找

// 得到斐波那契数列
public static int[] getFibonacci() {
    int max = 20;
    int[] f = new int[max];
    f[0] = 1;
    f[1] = 1;
    for (int i = 2; i < max; i++) {
        f[i] = f[i - 1] + f[i - 2];
    }
    return f;
}

public static int fibonacci(int[] arr, int value) {
    int low = 0;
    int high = arr.length - 1;
    // 获取到斐波那契数列分割数值的下标
    int k = 0;
    int mid = 0;

    int[] f = getFibonacci();

    // 拿到k
    while (high > f[k] - 1) {
        ++k;
    }
    // f[k]可能大于数组长度,扩容
    int[] temp = Arrays.copyOf(arr, f[k]);
    // 需要使用arr数组中最后的数填充
    for (int i = high + 1; i < temp.length; i++) {
        temp[i] = arr[high];
    }

    // 处理拿到k
    while (low <= high) {
        // 拿到mid
        mid = low + f[k - 1] - 1;
        if (value < arr[mid]) {
            // 向左
            high = mid - 1;
            --k;
        } else if (value > arr[mid]) {
            // 向右
            low = mid + 1;
            k -= 2;
        } else {
            // 找到
            if (mid <= high) {
                return mid;
            } else {
                return high;
            }
        }
    }
    return -1;
}
posted @ 2022-04-06 15:20  CoderCatIce  阅读(75)  评论(0编辑  收藏  举报