问大家一个问题啊
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;
}
}