zoukankan      html  css  js  c++  java
  • 有序表查找---斐波那契查找

        注意:斐波那契查找的前提和折半查找和插值查找的条件相同,即待查找的查找表必须是顺序存储且有序。
        斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=f(k)-1。
    开始将key值与第f(k-1)位置的记录进行比较(及mid=low+f(k-1)-1),比较结果也分为三种

    • key = a[mid]:mid位置的元素即为所求。
    • key < a[mid]:high=mid-1,k-=1
          high=mid-1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为f(k-1)-1 个,f(k-1)-1是怎么求出来的呢? [low, mid-1]中元素个数为:high-low+1=mid-1-low+1=low+f(k-1)-1-1-low+1=f(k-1)-1。所以可以递归 的应用斐波那契查找。
    • key > a[mid]:low=mid+1,k-=2
          low=mid+1说明待查找的元素在[mid+1,hign]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n - (f(k-1))= f(k)-1-f(k-1)=f(k)-f(k-1)-1f(k-2)-1个,所以可以递归的应用斐波那契查找。
      借鉴图片

    n=f(k)-1是为什么?
        是为了格式上的统一,以方便递归或者循环程序的编写。表中的数据是f(k)-1个,使用mid值进行分割又用掉一个,那么剩下f(k)-2个。正好分给两个子序列,每个子序列的个数分别是f(k-1)-1与f(k-2)-1个,格式上与之前是统一的。不然的话,每个子序列的元素个数有可能是f(k-1),f(k-1)-1,f(k-2),f(k-2)-1个,写程序会非常麻烦。

    代码如下(Java):

    import java.util.Arrays;
    
    public class FibonacciLookup {
    
    	public int max_size = 20;
    	public int[] f;
    	
    	public FibonacciLookup(int max_size) {
    		this.max_size = max_size;
    		this.f = new int[this.max_size];
    	}
    	
    	public FibonacciLookup() {
    		this.f = new int[this.max_size];
    	}
    	
    	public void Fibonacci() {
    		this.f[0] = 0;
    		this.f[1] = 1;
    		for (int i = 2; i < this.max_size; i++) {
    			this.f[i] = this.f[i - 1] + this.f[i - 2];
    		}
    	}
    	
    	public int Fibonacci_Search(int[] a, int n, int key) {
    		int low = 0, high = n - 1, mid;
    		int k = 0;
    		this.Fibonacci();
    		while(n > (this.f[k] - 1)) {
    			++k;
    		}
    		int[] temp = Arrays.copyOf(a, this.f[k] - 1);
    		
    		for (int i = n; i < temp.length; i++) {
    			if(i >= n) {
    				temp[i] = temp[n - 1];
    			}
    		}
    		
    		while(low <= high) {
    			mid = low + this.f[k - 1] - 1;
    			if(key < temp[mid]) {
    				high = mid - 1;
    				k=k-1;
    			}
    			else if(key > temp[mid]) {
    				low = mid + 1;
    				k = k-2;
    			}
    			else {
    				if(mid <= high) {
    					return mid;
    				}
    				else {
    					return high;
    				}
    			}
    		}
    		return -1;
    	}
    
    	public static void main(String[] args) {
    		int[] a = {1, 16, 24, 35, 47, 59, 62, 73, 88, 99};
    		FibonacciLookup f = new FibonacciLookup();
    		System.out.println(f.Fibonacci_Search(a, 10, 59));
    	}
    	
    }
    
  • 相关阅读:
    bootmgr is conmpressed联想Z485
    数据库中用开窗函数和复制表结构
    左连接新认识
    sql中的日期查询
    一个数据表通过另一个表更新数据(在UPDAT语句中使用FROM子句)
    StarUML安装与Win7不兼容解决
    SQL中VARCHAR与NVARCHAR存储区别
    Cannot start service SPUserCodeV4 on computer
    SQL中空值与NULL区别
    验证码破解分析
  • 原文地址:https://www.cnblogs.com/lishanlei/p/10707799.html
Copyright © 2011-2022 走看看