对斐波那契查找的一点疑问?

问大家一个问题啊

Java小白,最近在看数据结构与算法,下面是我的疑惑,问题在代码注释中

主函数采用了随机数,来保证数组值、查找的元素的客观性,经自己测试,得出的结果是我自己想的“斐波那契”查找,要比 斐波那契查找 快得多。
知道的不多,只能用随机数,比较运算时间的方式来验证

我自己想的“斐波那契”查找

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;

/**
 * @author MrThreePA
 * 2020/4/12
 */
public class Fib618Search {
    public static void main(String[] args) {
        int[] arr = new int[1000000];
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(1000000);
        }
        // 随机找一个数num
        int num = random.nextInt(10000);
        System.out.println(num);
        // 对arr数组进行排序
        Arrays.sort(arr);
        // 输出找出num前后的时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
        String s1 = sdf.format(date);
        System.out.println(s1);
        // 在排好序的数组中找出num
        int index = search(arr, num);
        date = new Date();
        String s2 = sdf.format(date);
        System.out.println(s2);
		// 验证正确性
        System.out.println("index = " + index);
        if (index != -1) {
            System.out.println("arr[" + index + "] = " + arr[index]);
        }
    }
    public static int search(int[] arr, int key) {
        int low = 0;
        int high = arr.length - 1;
        int mid = 0;
        while (low <= high) {
            // 斐波那契数列,前后两数之比是0.618,那为什么不直接在这里乘0.618呢?
            // 还是说频繁调用Math.floor函数,耗时多?
            // 但是我觉得肯定比原斐波那契查找调用多次循环的速度快
            // 疑问?
            // 斐波那契查找对于二分查找的优化在哪儿?
            // 那斐波那契查找存在的意义是什么?
            mid = low + (int)Math.floor((high - low) * 0.618);
            
            if (key > arr[mid]) {
                low = mid + 1;
            } else if (key < arr[mid]) {
                high = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

原斐波那契查找 里面就不做注解了

 import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;

/**
 * @author MrThreePA
 * 2020/4/12
 */
public class FiberSearch {
    static int max = 100;
    public static void main(String[] args) {
        int[] arr = new int[1000000];
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(10000000);
        }
        // 随机找一个数num
        int num = arr[random.nextInt(1000000)];
        System.out.println(num);
        Arrays.sort(arr);

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss SSS");
        String s1 = sdf.format(date);
        System.out.println(s1);
        // 在排好序的数组中找出num
        int index = fibSearch(arr, num);
        date = new Date();
        String s2 = sdf.format(date);
        System.out.println(s2);

        System.out.println(arr[index]);
    }
    public static int[] fibNum() {
        int[] f = new int[max];
        f[0] = 1;
        f[1] = 1;
        for (int i = 2; i < f.length; i++) {
            f[i] = f[i - 1] + f[i - 2];
        }
        return f;
    }
    public static int fibSearch(int[] arr, int key) {
        int low = 0;
        int high = arr.length - 1;
        int k = 0;
        int mid = 0;
        int[] f = fibNum();
        while (arr.length > f[k] - 1) {
            k++;
        }
        int[] temp = Arrays.copyOf(arr, f[k]);
        for (int i = high + 1; i < temp.length; i++) {
            temp[i] = arr[high];
        }
        while (low <= high) {
            mid = low + f[k - 1] - 1;
            if (key < temp[mid]) {
                high = mid - 1;
                k--;
            } else if (key > temp[mid]) {
                low = mid + 1;
                k -= 2;
            } else {
                if (mid <= high) {
                    return mid;
                } else {
                    return high;
                }
            }
        }
        return -1;
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值