斐波那契搜索---java实现

斐波那契搜索

1、介绍

斐波那契搜索是对二分查找的一种改进,针对的依然是有序序列

2、实现

import java.util.Arrays;

/**
 * @author Exticntion
 */
public class FibonacciSearch {
    public static int maxSize = 20;
    private static int count = 0;

    public static void main(String[] args) {
        // 创造一个有序数组
        int[] sequence = new int[100];
        for (int i = 0; i < sequence.length; i++) {
            sequence[i] = i + 1;
        }
        int res = fibonacciSearch(sequence, 98);
        System.out.println("查找结果:" + res);

    }

    /**
     * fibonacci search
     *
     * @param array array
     * @param key   key
     * @return {@link int} 找到就返回数组下标,没有则返回-1
     */
    public static int fibonacciSearch(int[] array, int key) {
        int low = 0;
        int high = array.length - 1;
        int mid = 0;
        // k 表示斐波那契数列分割数值的下标
        int k = 0;
        int[] fib = fib();
        System.out.println("斐波那契数列如下:");
        System.out.println(Arrays.toString(fib));
        // 获取斐波那契数列分割的下标,因为要确保斐波那契数列的长度大于等于数组的长度
        while (high > fib[k] - 1) {
            k++;
        }
        // 因为 fib[k] 可能大于数组的长度,所以要对数组进行填充,用最后一个值进行填充
        // 用 arrays 类复制,不足的部分会用 0 填充
        int[] temp = Arrays.copyOf(array, fib[k]);
        for (int i = high + 1; i < temp.length; i++) {
            temp[i] = array[high];
        }

        // 使用while循环来处理
        while (low <= high) {
            count++;
            System.out.println("遍历次数~~~" + count);
            mid = low + fib[k - 1] - 1;
            //我们应该继续向数组的前面查找(左边)
            if (key < temp[mid]) {
                high = mid - 1;
                // 要更新 k 的值
                //说明
                //1. 全部元素 = 前面的元素 + 后边元素
                //2. f[k] = f[k-1] + f[k-2]
                //因为前面有 f[k-1] 个元素,所以可以继续拆分 f[k-1] = f[k-2] + f[k-3]
                //即在 f[k-1] 的前面继续查找 k--
                //即下次循环 mid = f[k-1-1]-1
                k--;
                // 我们应该继续向数组的后面查找(右边)
            } else if (key > temp[mid]) {
                low = mid + 1;
                //说明
                //1. 全部元素 = 前面的元素 + 后边元素
                //2. f[k] = f[k-1] + f[k-2]
                //3. 因为后面我们有f[k-2] 所以可以继续拆分 f[k-1] = f[k-3] + f[k-4]
                //4. 即在f[k-2] 的前面进行查找 k -=2
                //5. 即下次循环 mid = f[k - 1 - 2] - 1
                k -= 2;
            } else {
                //还需要确定返回的是哪个下标
                if (mid <= high) {
                    return mid;
                } else {
                    return high;
                }
            }

        }
        return -1;

    }

    /**
     * 创建斐波那契数列
     * 使用非递归的方式实现斐波那契数列,并返回了斐波那契数组
     */
    public static int[] fib() {
        int[] sequence = new int[maxSize];
        sequence[0] = 1;
        sequence[1] = 1;
        for (int i = 2; i < maxSize; i++) {
            sequence[i] = sequence[i - 1] + sequence[i - 2];
        }
        return sequence;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Exticntion

跪谢大佬的赞助!祝您万事如意!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值