查找算法----斐波那契查找

这篇博客介绍了斐波那契查找算法,它是一种改进的二分查找技术,利用斐波那契数列特性提高查找效率。时间复杂度为O(logn)。文章通过代码展示了如何在有序数组中实现斐波那契查找,并与插入查找、二分查找和顺序查找进行了效率比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 斐波那契查找:斐波那契搜索也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。 同样地,斐波那契查找也属于一种有序查找算法,必须在有序的结构中才能进行查找。 斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。

2. 斐波那契查找的时间复杂度:斐波那契查找的时间复杂度为O( logn )

3. 斐波那契查找的实现:


//查找算法 斐波那契查找 该查找方法的效率要低于插入查找的效率但是高于二分查找的效率
//查找效率:插入查找 > 斐波那契查找 > 二分查找 > 顺序查找
public class FeibonacciSearch {
	public static void main(String[] args) {
		int[] arr = {1, 5, 7, 10, 40, 50, 56, 67, 79, 80, 99};
		int key = 50;
		int index = feibonacciSearch(arr, key);
		System.out.println("index:" + index);
	}

	//斐波那契查找
	private static int feibonacciSearch(int[] arr, int key) {
		int low = 0; 
		int high = arr.length - 1;
		int mid = 0; //是arr数组或者temp数组的索引
		
		int[] f = getFeiArr(); //获取斐波那契数列
		
		int k = 0; //表示斐波那契数列的索引
		/*
		 * 当要查找的数组长度大于斐波那契数列k位置的值时,
		 * 就更新k的值 直到斐波那契数列k位置的值大于arr数组的长度
		 */
		while(arr.length > f[k]) {
			k++;
			//要求斐波那契数列中k位置的值是斐波那契数列中最小的大于high的值
			//最后斐波那契数列中k位置的值 就是我们要创建的新数组的长度
		}
		
		//重新创建一个数组 将arr数组复制进新数组 新数组长度为斐波那契数列k位置的值
		//要保证该值是能将arr数组包含进去且最小的值
		int[] temp = Arrays.copyOf(arr, f[k]);
		//将新数组多余出来的位置的值 全部填成原数组high位置的值
		for(int i = high + 1; i < temp.length; i++) {
			temp[i] = high;
		}
		
		while(low <= high) { //当low大于high 则说明没有找到指定元素
			
			mid = low + f[k - 1] - 1; //为mid赋值,mid的值为:low加上斐波那契数列k-1位置的值减1
			
			//如果要查找的值大于新数组mid位置的值 low指针就等于mid+1 
			//使k指向斐波那契数列中构成现temp数组的长度的值的小的那一部分的位置
			if(key > temp[mid]) { 
				low = mid + 1;
				k -= 2;
			//如果要查找的值小于新数组mid位置的值 high指针就等于mid-1 
			//使k指向斐波那契数列中构成现temp数组的长度的值的大的那一部分的位置
			}else if(key < temp[mid]) {
				high = mid - 1;
				k -= 1;
			//如果以上条件不满足 mid位置的值就是要寻找的值 但是还有做一个判断
			}else {
				//如果mid小于等于high 则说明mid就是要找的值的索引
				if(mid <= high) {
					return mid;
				//如果mid大于等于high 则说明high才是要找的值在原数组的索引
				}else {
					return high;
				}
			}
		}
		//如果没有找到 就返回-1
		return -1;
	}

	//获取斐波那契数列
	private static int[] getFeiArr() {
		int[] f = new int[20];
		f[1] = 1;
		f[2] = 1;
		for(int i = 2; i < f.length; i++) {
			f[i] = f[i - 1] + f[i - 2];
		}
		return f;
	}
}

4. 运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值