栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Day570.斐波那契查找算法 -数据结构和算法Java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Day570.斐波那契查找算法 -数据结构和算法Java

斐波那契查找算法 一、介绍

二、工作原理

三、代码实现
package com.achang.search;

import java.util.Arrays;


public class FibonaciiSearch {

    public static int maxSize = 20;

    public static void main(String[] args) {
        int[] arr = {1, 8, 10, 89, 1000, 1234};
        System.out.println(fibonaciiSearch(arr,2));
    }


    //因为后面mid=low+F(k-1)-1,需要使用到斐波那契数列,因此需要构建一个斐波那契数列
    //使用非递归的方式获取斐波那契数列
    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 fibonaciiSearch(int[] arr, int findValue) {
        int low = 0;
        int high = arr.length - 1;
        int k = 0;//表示斐波那契分割数值的下标,也就是mid=low+F(k-1)-1的k值
        int mid = 0;//初始化mid为0;
        int[] f = fib();//斐波那契数列

        //获取到斐波那契分割数值的下标,也就是k
        while (high > f[k] - 1) {
            k++;
        }
        //因为f[k]可能大于数组的长度,因此需要Arrays类,构造一个新的数组,并指向temp
        //不足的部分,会使用0填充
        int[] temp = Arrays.copyOf(arr, f[k]);
        //实际上需要使用arr数组最后的数填充temp,将为默认0填充的填充为arr数字中最后的数值
        //temp = {1,8,10,89,1000,1234} ===> {1,8,10,89,1000,1234,1234,1234,1234}
        for (int i = high + 1; i < temp.length; i++) {
            temp[i] = arr[high];
        }

        //使用while循环处理,找到我们的k值
        while (low <= high) {
            mid = low + f[k - 1] - 1;
            if (findValue < temp[mid]) {
                //继续向数组的左边查找
                high = mid - 1;
                //1、全部元素 = 前面的元素 + 后边的元素
                //2、f[k] = f[k-1] + f[f-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 (findValue > temp[mid]) {
                //继续向数组的右边查找
                low = mid + 1;
                //1、全部元素 = 前面的元素 + 后边的元素
                //2、f[k] = f[k-1] + f[f-2]
                //3、 因为后面有f[k-2],继续拆分 f[k-1] = f[k-3] + f[f-4]
                //4、在f[k-2]前面进行查找,所以k-2,下次循环mid = f[k-1-2]-1;
                k -= 2;
            } else {
                //找到了,需要确定返回的是哪个下标
                if (mid <= high) {
                    //在high数组范围内,就范围mid
                    return mid;
                } else {
                    //不然就是在数组范围外,就返回high
                    return high;
                }
            }
        }
        return -1;
    }


}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781130.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号