斐波那契查找算法java版

来源:互联网 发布:ipad1如何下载软件 编辑:程序博客网 时间:2024/06/05 21:07

与二分查找相比,斐波那契查找算法的明显优点在于它只涉及加法和减法算,而不用除法。因为除法比加减法要占去更多的机时,因此,斐波那契查找的平均性能要比折半查找好。



public class Fibonacci_Search {

    privateint[] FibonacciList;

    public void Fibonacci(int n) {
       FibonacciList = new int[n];
       FibonacciList[0] = 0;
       FibonacciList[1] = 1;
       for (int i = 2; i < n; i++) {
           FibonacciList[i] = FibonacciList[i - 1] + FibonacciList[i -2];
       }
   }


    public int FibonacciSearch(int key, ArrayList data, intn) {
       Fibonacci(n);
       int low, high, mid, i, k;
       low = 1;
       high = n;
       k = 0;
       //找到在斐波那契数列中对应的位置。如需要查询的数组长度为10,则在斐波那契数列的6和7之间,则      //k=7;
       while (n > this.FibonacciList[k] - 1) {
           k++;
       }
       //由于Fibonacci[7]=13,于是11和12都为空,避免出现查询空值,因此将其复制为data[10];
       for (i = n; i < FibonacciList[k] - 1; i++) {
           data.add(data.get(n));
       }
       while (low <= high) {
           mid = low + FibonacciList[k - 1] - 1;
           if (key < data.get(mid)) {
               high = mid - 1;
               k--;
           } else if (key > data.get(mid)) {
               low = mid + 1;
               k = k - 2;
           } else {
               if (mid <= n) {
                   return mid;
               } else {
                   return n;
               }
           }
       }
       return 0;
   }


解析:
首先要明确:如果一个有序表的元素个数为n,并且n正好是(某个斐波那契数 - 1),即n=F[k]-1时,才能用斐波那契查找法。如果有序表的元素个n不等于(某个斐波那契数 - 1),即n≠F[k]-1,这时必须要将有序表的元素扩展到大于n的那个斐波那契数 -1才行,这段代码:
for (int i = n; i < F[k] - 1; i++)
 
{
  a[i] = a[high];
  }
便是这个作用。

下面回答
第一个问题:看完上面所述应该知道①是为什么了吧。 查找n在斐波那契数列中的位置,为什么是F[k] -1,而不是F[k],是因为能否用斐波那契查找法是由F[k]-1决定的,而不是F[k]。如果暂时不理解,继续看下面。

第二个问题:a的长度其实很好估算,比如你定义了有10个元素的有序数组a[20],n=10,那么n就位于8和13,即F[6]和F[7]之间,所以k=7,此时数组a的元素个数要被扩充,为:F[7] - 1 = 12个;再如你定义了一个b[20],且b有12个元素,即n=12,那么很好办了,n = F[7]-1 = 12, 用不着扩充了;又或者n=8或9或11,则它一定会被扩充到12;再如你举的例子,n=13,最后得出n位于13和21,即F[7]和F[8]之间,此时k=8,那么F[8]-1 =20,数组a就要有20个元素了。 所以,n =x(13<=x<=20)时,最后都要被扩充到20;类推,如果n=25呢,则数组a的元素个数肯定要被扩充到 34 - 1 =33个(25位于21和34,即F[8]和F[9]之间,此时k=9,F[9]-1 = 33),所以,n =x(21<=x<=33)时,最后都要被扩充到33。也就是说,最后数组的元素个数一定是(某个斐波那契数 -1),这就是一开始说的n与F[k]-1的关系。

第三个问题:对于二分查找,分割是从mid= (low+high)/2开始;而对于斐波那契查找,分割是从mid = low +F[k-1] - 1开始的;通过上面知道了,数组a现在的元素个数为F[k]-1个,即数组长为F[k]-1,mid把数组分成了左右两部分,左边的长度为:F[k-1] - 1, 那么右边的长度就为(数组长-左边的长度-1), 即:(F[k]-1) - (F[k-1] -1) = F[k] - F[k-1] - 1 = F[k-2] - 1。 
斐波那契查找的核心是:
  1)当key=a[mid]时,查找成功;
  2)当key
 3)当key>a[mid]时,新的查找范围是第mid+1个到第high个,此时范围个数为F[k-2] -1个,即数组右边的长度,所以要在[F[k - 2] - 1]范围内查找。
0 0
原创粉丝点击