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


1、算法介紹

 斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….,隨着數列遞增,前后兩個數的比值趨近於0.618的黃金分割比。

斐波那契查找便是將黃金比例運用於查找中。

(1)查找序列arr元素個數:n

(2)斐波那契數:F(1)=1,F(2)=1, F(k)=F(k-1)+F(k-2)(k>=3,k∈N*);

(3)構建新的查找序列arrNew元素個數:m = F(k)-1,需滿足 m 大於等於 n,即F(k)-1>=n

(4)取F(k)-1的原因:F(k)-1= F(k-1)-1 + F(k-2)-1 + 一個查找數

如 F(7)-1 = 13-1 = F(6)-1 + F(5)-1 + 1 = 8-1 + 5-1 + 1

(5)新的查找序列arrNew前面數據與arr相同,后面多余位的值全部等於arr[n-1]

(6)查找規則類似二分查找

2、代碼實現

 2.1、golang

package main

import (
	"fmt"
)

func main() {
	fib := CreateFibnacci(20)
	fmt.Println(fib)
	slice := []int{1, 2, 3, 4, 5, 6} //升序序列
	key := 100
	index := SearchFibnacci(slice, key)
	if index == -1 {
		fmt.Printf("%v不存在元素%v\n", slice, key)
	} else {
		fmt.Printf("%v位於%v下標為%v的位置。\n", key, slice, index)
	}
}

//構建斐波那契數列
func CreateFibnacci(n int) []int {
	res := []int{1, 1}
	for i := 2; i < n; i++ {
		res = append(res, res[i-1]+res[i-2])
	}
	return res
}

//斐波那契查找
func SearchFibnacci(slice []int, key int) int {
	n := len(slice)
	fib := CreateFibnacci(20)
	//1、斐波那契下標,需滿足F(k)-1>=n
	k := 0
	for !(fib[k]-1 >= n) {
		k++
	}
	//2、構建新序列,多出位補slice[n-1]
	tempS := make([]int, fib[k]-1)
	copy(tempS, slice)
	for i := n; i < len(tempS); i++ {
		tempS[i] = slice[n-1]
	}
	//3、開始斐波那契查找
	left, right := 0, n-1
	for left <= right {
		mid := left + fib[k-1] - 1
		if tempS[mid] > key {
			right = mid - 1
			k -= 1 //查找值在前面的F(k-1)位中
		} else if tempS[mid] < key {
			left = mid + 1
			k -= 2 //查找值在后面的F(k-2)位中
		} else {
			if mid < n {
				return mid
			} else { //位於tempS的填補位
				return n - 1
			}
		}
	}
	return -1
}

2.2、python3

# 4、斐波那契查找
def create_fibonacci(n):
    arr = [1, 1]
    for i in range(2, n, 1):
        arr.append(arr[i - 1] + arr[i - 2])
    return arr


# 斐波那契查找
def serarch_fibonacci(arr, key):
    n = len(arr)
    # 創建斐波那契數組
    fib_arr = create_fibonacci(20)
    print(fib_arr)
    # 獲取斐波那契下標,需滿足F(k)-1>=n
    k = 0
    while not (fib_arr[k] - 1 >= n):
        k += 1
    # 構建新序列,多出位補arr[n-1]
    tempArr = arr.copy()
    for i in range(n, fib_arr[k] - 1, 1):
        tempArr.append(arr[n - 1])
    print(tempArr)
    # 開始查找
    left, right = 0, n - 1
    while (left <= right):
        mid = left + fib_arr[k - 1] - 1
        if (tempArr[mid] > key):
            right = mid - 1
            k -= 1
        elif (tempArr[mid] < key):
            left = mid + 1
            k -= 2
        else:
            if (mid < n):
                return mid
            else:
                return n - 1
    return -1


if __name__ == '__main__':
    arr = [1, 2, 3, 4, 5, 6, 7, 8]
    key = 7
    index = serarch_fibonacci(arr, key)
    if index == -1:
        print("%s不存在元素%s。" % (arr, key))
    else:
        print("%s位於%s下標為%s的位置。" % (key, arr, index))

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM