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


    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
    ", slice, key)
    	} else {
    		fmt.Printf("%v位于%v下标为%v的位置。
    ", 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))
    

      

    笃志:“博学而笃志,切问而近思,仁在其中矣。”
    弘毅:“士不可以不弘毅,任重而道远。”
    止于至善:“大学之道,在明明德,在亲民,在止于至善。”
    关注:笃志弘毅,止于至善
  • 相关阅读:
    devise 异步发邮件
    ubuntutweak for lucid
    960gs blueprint
    Amoeba for mysql 0.31发布(读写分离、负载均衡、Failover、数据切分)
    Google App Servlet容器转型 – 从Tomcat到Jetty
    DBeaver
    用simple from暂不用formtastic
    [SQL Server]ORDER BY的问题
    PHP pathinfo() 函数
    php中使用head进行二进制流输出,让用户下载PDF等附件的方法
  • 原文地址:https://www.cnblogs.com/dzhy/p/10948398.html
Copyright © 2020-2023  润新知