斐波那契查找算法

算法原理:

斐波那契查找就是在二分查找的基礎上根據(jù)斐波那契數(shù)列進行分割的含思。

  1. 構建一個斐波那契數(shù)列
  2. 擴展被查詢數(shù)列:在斐波那契數(shù)列找一個等于略大于查找表中元素個數(shù)的數(shù)F[n],將原查找表擴展為長度為F[n](如果要補充元素险绘,則補充重復最后一個元素毒涧,直到滿足F[n]個元素)
  3. 查找元素:對擴展后的被查詢數(shù)列進行斐波那契分割,即F[n]個元素分割為前半部分F[n-1]個元素鉴分,后半部分F[n-2]個元素劣砍,找出要查找的元素在那一部分并遞歸惧蛹,直到找到。
時間復雜度:

時間復雜度 O(log 2 n )

對比二分法查找:

二者時間復雜度一樣都是O(log 2 n )刑枝,但是與二分法查找相比香嗓,

斐波那契查找的優(yōu)點是它只涉及加法和減法運算,而不用除法装畅,而除法比加減法要占用更多的時間靠娱,

因此,斐波那契查找的運行時間理論上比折半查找小掠兄,但是還是得視具體情況而定饱岸。


package com.study.java.al;

import java.util.Arrays;

/**
 *
 * 斐波那契查找算法
 * 步驟概述:
 * 1. 構建一個斐波那契數(shù)列
 * 2. 擴展被查詢數(shù)列:在斐波那契數(shù)列找一個等于略大于查找表中元素個數(shù)的數(shù)F[n],將原查找表擴展為長度為F[n](如果要補充元素徽千,則補充重復最后一個元素,直到滿足F[n]個元素)汤锨,
 * 3. 查找元素:對擴展后的被查詢數(shù)列進行斐波那契分割双抽,即F[n]個元素分割為前半部分F[n-1]個元素,后半部分F[n-2]個元素闲礼,找出要查找的元素在那一部分并遞歸牍汹,直到找到。
 */

/**
 * @author ahdkkyxq
 */
public class FibonacciSearch {

    /**
     * @param args
     */
    public final static int MAXSIZE = 10;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] f = fibonacci();
        // 打印fib數(shù)組
        System.out.println("斐波那契數(shù)列: "+Arrays.toString(f));
        int[] data = {1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68, 88};
        System.out.println("被查詢數(shù)列: "+Arrays.toString(data));
        int search = 39;
        System.out.println("查詢目標: "+search);
        int position = fibonacciSearch(data, search);
        System.out.println("值" + search + "的元素位置為:" + position);
    }

    /**
     * 斐波那契數(shù)列
     *
     * @return
     */
    public static int[] fibonacci() {
        int[] f = new int[MAXSIZE];
        int i = 0;
        f[0] = 1;
        f[1] = 1;
        for (i = 2; i < MAXSIZE; i++) {
            f[i] = f[i - 1] + f[i - 2];
        }
        return f;
    }

    public static int fibonacciSearch(int[] data, int key) {
        int low = 0;
        int high = data.length - 1;
        int mid = 0;

        // 斐波那契分割數(shù)值下標
        int k = 0;

        // 序列元素個數(shù)
        int i = 0;

        // 獲取斐波那契數(shù)列
        int[] f = fibonacci();

        // 獲取斐波那契分割數(shù)值下標
        while (data.length > f[k] - 1) {
            k++;
        }

        // 創(chuàng)建臨時數(shù)組,長度為fib的值-1柬泽,并復制原數(shù)組的內(nèi)容到新數(shù)組
        int[] temp = new int[f[k] - 1];
        for (int j = 0; j < data.length;j++){
            temp[j] = data[j];
        }
        // 序列補充至f[k]個元素
        // 補充的元素值為最后一個元素的值
        for (i = data.length; i < f[k] - 1; i++) {
            temp[i] = temp[high];
        }
        // 打印數(shù)組
        System.out.println("被查詢數(shù)組擴容: "+Arrays.toString(temp));

        while (low <= high) {
            // low:起始位置
            // 前半部分有f[k-1]個元素慎菲,由于下標從0開始
            // 則-1 獲取 黃金分割位置元素的下標
            mid = low + f[k - 1] - 1;

            if (temp[mid] > key) {
                // 查找前半部分,高位指針移動
                high = mid - 1;
                // (全部元素) = (前半部分)+(后半部分)
                // f[k] = f[k-1] + f[k-1]
                // 因為前半部分有f[k-1]個元素锨并,所以 k = k-1
                k = k - 1;
            } else if (temp[mid] < key) {
                // 查找后半部分露该,高位指針移動
                low = mid + 1;
                // (全部元素) = (前半部分)+(后半部分)
                // f[k] = f[k-1] + f[k-1]
                // 因為后半部分有f[k-1]個元素,所以 k = k-2
                k = k - 2;
            } else {
                // 如果為真則找到相應的位置
                if (mid <= high) {
                    return mid;
                } else {
                    // 出現(xiàn)這種情況是查找到補充的元素
                    // 而補充的元素與high位置的元素一樣
                    return high;
                }
            }
        }
        return -1;
    }
}

運算結果:
AAAA-07.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末第煮,一起剝皮案震驚了整個濱河市解幼,隨后出現(xiàn)的幾起案子抑党,更是在濱河造成了極大的恐慌,老刑警劉巖撵摆,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件底靠,死亡現(xiàn)場離奇詭異,居然都是意外死亡特铝,警方通過查閱死者的電腦和手機暑中,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲫剿,“玉大人鳄逾,你說我怎么就攤上這事∏K兀” “怎么了严衬?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長笆呆。 經(jīng)常有香客問我请琳,道長,這世上最難降的妖魔是什么赠幕? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任俄精,我火速辦了婚禮,結果婚禮上榕堰,老公的妹妹穿的比我還像新娘竖慧。我一直安慰自己,他們只是感情好逆屡,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布圾旨。 她就那樣靜靜地躺著,像睡著了一般魏蔗。 火紅的嫁衣襯著肌膚如雪砍的。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天莺治,我揣著相機與錄音廓鞠,去河邊找鬼。 笑死谣旁,一個胖子當著我的面吹牛床佳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榄审,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼砌们,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起怨绣,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤角溃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后篮撑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體减细,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年赢笨,在試婚紗的時候發(fā)現(xiàn)自己被綠了未蝌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡茧妒,死狀恐怖萧吠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桐筏,我是刑警寧澤纸型,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站梅忌,受9級特大地震影響狰腌,放射性物質發(fā)生泄漏。R本人自食惡果不足惜牧氮,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一琼腔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧踱葛,春花似錦丹莲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至性含,卻和暖如春洲赵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胶滋。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留悲敷,地道東北人究恤。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像后德,于是被迫代替她去往敵國和親部宿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349