java实现斐波那契查找算法

斐波那契查找算法:前提是一个有序数组。
斐波那契数列:1,1,2,3,5,8,13,21。。。。。。
主要思想:通过斐波那契数列找到数组黄金分割点附近的下标,即mid。
在这里插入图片描述
根据上图所示:假设有一个数组,数组里面的元素有F[k]-1个,这个数组被分成了三份:F[k-1]-1,1和F[k-2]-1这三份(mid点是一个元素,长度为1)。
根据斐波那契数列的公式:
F[k]=F[k-1]+ F[k-2],将这个公式变型为F[k]-1=F[k-1]-1+ F[k-2]-1+1。
根据斐波那契查找法,mid的选择方法为mid = low+F[k-1]-1,使mid位于黄金分割点附近。
在这里插入图片描述
例如上图所示:low=0,F[k-1]-1=4,mid= 4。所以k=4时:4=0+5-1。
当数组的元素为{1,2,3,4,5,6}时,为了满足斐波那契数列,数组的长度需要满足:
While(array.Length > F[k]-1){
K++;
}
K=0开始每次加1,直到F[k]-1的值大于或等于数组的长度为止。
因此,根据这个条件,上面的数组长度为6,在k=5时,F[5] – 1=7,数组需要正价长度及元素,将数组长度变为7,在后面赋值数据最后一个元素的值。

```package SearchTest;

import java.util.Arrays;

public class FibonacciSearchTest {
	public static int max = 20;// 定义斐波那契数列的长度
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr = { 1, 8, 10, 89, 100, 123, 200 };
		System.out.println(FibonacciSearch(arr, 123));
	}

	// 实现一个斐波那契数列的方法
	// 1,1,2,3,5,8,13,21,34,55......
	public static int[] Fibonacci() {
		int[] F = new int[max];
		F[0] = 1;
		F[1] = 1;
		for (int i = 2; i < max; i++) {
			F[i] = F[i - 1] + F[i - 2];
		}
		return F;
	}

	// 实现斐波那契查找的步骤
	public static int FibonacciSearch(int[] arr, int findVal) {
		int low = 0;// 数据的左边下标
		int high = arr.length - 1;// 数组的右边下标
		int[] f = Fibonacci();// 将斐波那契数列传递给f数组
		int k = 0;// 用来弥补F[k]-1余arr.Length的差距
		int mid = 0;// 黄金分割点
		// 判断数组的长度是否小于F[k]-1,如果小于就用k计数
		// 这个地方是数组长度与斐波那契数列中的数据进行比较
		// 因此,数组的长度是arr.Length,
		while (arr.length > f[k] - 1) {// f[5] = 8,high = 5;
			k++;// 直到找到一个k的值,可以使f[k]-1大于high时结束,k为斐波那契数列下标
		}
		// 这时需要填充数组arr,需要达到斐波那契数列的长度
		// 但是arr得长度已经固定了,因此需要一个临时的数组
		int[] tmp = Arrays.copyOf(arr, f[k] - 1);//
		for (int i = high + 1; i < tmp.length; i++) {
			tmp[i] = arr[high];
		}
		// 开始循环
		while (low <= high) {
			mid = low + f[k - 1] - 1;// 黄金分割点
			if (findVal < tmp[mid]) {
				high = mid - 1;
				// 这个k=k-1可以理解为现在对新的数组进行查找,也是斐波那契数列,此时的数据长度为F[k-1]-1
				// 现在可以令k-1=K,这样这个数组的长度可以写成F[K]-1,mid = low+F[K-1]-1即low+F[k-2]-1
				k = k - 1;//
			} else if (findVal > tmp[mid]) {
				low = mid + 1;
				// 这个k=k-2可以理解为现在对新的数组进行查找,也是斐波那契数列,此时的数据长度为F[k-2]-1
				// 现在可以令k-2=K,这样这个数组的长度可以写成F[K]-1,mid = low+F[K-1]-1即low+F[k-3]-1
				k = k - 2;
			} else {// 由于数组后面的数据都是最后一个元素填充的,mid可能是那些填充数据的下标,因此需要比较与真实数组长度的大小
				if (mid <= high) {
					return mid;
				} else {
					return high;
				}
			}
		}
		return -1;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值