算法:静态查找表(Static Search Table)(顺序查找、二分查找、插值查找、斐波纳契查找)

转载

BinarySearch.java

/**
 * @ClassName BinarySearch
 * @Description 折半查找
 *
 *  可以使用插值公式将折半查找性能优化
 *
 *  只需将其中的 mid = (low+high) / 2 = low + 1/2*(high-low)
 *  改为 mid = low + (high-low) * (key-a[low]) / (a[high]-a[low])
 *
 * @Author zk_kiger
 * @Date 2019/12/17 20:26
 * @Version 1.0
 */

public class BinarySearch {

    // 非递归
    public int binarySearch(int[] array, int n, int key) {
        int low, high, mid;
        low = 0;
        high = n-1;

        while (low <= high) {
            mid = (low+high) / 2;
            if (key < mid)
                high = mid -1;
            else if (key > mid)
                low = mid + 1;
            else
                return mid;
        }

        return 0;
    }

    // 递归
    public int binarySearchD(int[] array, int key, int low, int high) {
        if (low > high)
            return 0;

        int mid = (low+high) / 2;

        if (key < mid)
            binarySearchD(array, key, low, mid-1);
        else if (key > mid)
            binarySearchD(array, key, mid+1, high);
        else
            return mid;

        return 0;
    }

}

FibonacciSearch.java

/**
 * @ClassName FibonacciSearch
 * @Description 斐波那契查找
 *  思路:
 *      在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],
 *      将原查找表扩展为长度为F[n](如果要补充元素,则补充重复最后一个元素,
 *      直到满足F[n]个元素),完成后进行斐波那契分割,即F[n]个元素分割为
 *      前半部分F[n-1]个元素,后半部分F[n-2]个元素,找出要查找的元素在那一部分并递归,直到找到。
 *
 * @Author zk_kiger
 * @Date 2019/12/17 20:40
 * @Version 1.0
 */

public class FibonacciSearch {

    // 用来存储斐波那契数列
    private int[] fib = {1,1,2,3,5,8,13,21,34};

    public int fibonacciSearch(int[] array, int n, int key) {
        int low, high, mid, k;
        low = 0;
        high = n-1;
        k = 0;

        // 找到有序元素个数在斐波那契数列中最接近的最大数列值
        while (n > fib[k])
            ++k;
        // 补齐有序表
        for (int i = n; i <= fib[k]; i++) {
            array[i] = array[high];
        }

        while (low <= high) {
            // 计算当前分割的下标
            mid = low + fib[k-1]-1;

            if (key < mid) {
                high = mid - 1;
                // 若在左半区,那么下一次查找有序元素个数为 fib[k-1]-1
                k -= 1;
            }
            else if (key > mid) {
                low = mid + 1;
                // 若在右半区,那么下一次查找有序元素个数为 fib[k-2]-1
                k -= 2;
            }
            else {
                if (mid <= n-1)
                    return mid;
                else {
                    // 说明查找得到的数据元素是补全值
                    return n-1;
                }
            }

        }

        return 0;
    }

}
发布了120 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43327091/article/details/103652424
今日推荐