斐波那契查找

using System;
using System.Collections.Generic;

namespace TestCSharp
{
    class Program
    {
        // 斐波那契数列:从第三个元素开始,本项是前两项的和。即F[k] = F[k-1] + F[k-2]
        // 斐波那契数列的性质:长度为 F[k-1] - 1 的数列,去掉对应切分点元素,可以分成左右两个子数列。
        // 左边数列长度为 F[k-1] - 1, 右边数列长度为 F[k-2] - 1, 切分点元素占位长度为1, 因此总长度为 F[k-1] - 1 == F[k-1] - 1 + 1 + F[k-2] - 1
        static void Main(string[] args)
        {
            int[] array = { 1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68 };
            Console.WriteLine("result: " + FibonacciSearch(array, 68));
            Console.ReadKey();
        }

        public static int FibonacciSearch(int[] list, int targetValue)
        {
            // create fibonacci array. 
            int[] F = CreateFibonacciArray(list.Length); // TODO
            int k = 0;
            while (list.Length > F[k] - 1)
            {
                k++;
            }

            // create a array whose length is F[k] - 1. 
            int[] fullList = new int[F[k] - 1];
            for (int i = 0, length = fullList.Length; i < length; i++)
            {
                if (i < list.Length)
                {
                    fullList[i] = list[i];
                }
                else
                {
                    fullList[i] = list[list.Length - 1];
                }
            }

            // recurse mode. 
            return RecurseFind(fullList, F, targetValue, 0, list.Length - 1, k);

            // find target value. 
            int low = 0;
            int high = list.Length - 1;
            int mid = 0;
            while (low <= high)
            {
                mid = low + F[k - 1] - 1;
                if (targetValue < fullList[mid])
                {
                    high = mid - 1;
                    k = k - 1;
                }
                else if (targetValue > fullList[mid])
                {
                    low = mid + 1;
                    k = k - 2;
                }
                else
                {
                    if (mid < list.Length)
                    {
                        return mid;
                    }
                    return list.Length - 1;
                }
            }
            return -1;
        }

        public static int[] CreateFibonacciArray(int length)
        {
            if (length < 2)
            {
                return null;
            }

            int[] array = new int[length];
            array[0] = 1;
            array[1] = 1;
            for (int i = 2, max = array.Length; i < max; i++)
            {
                array[i] = array[i - 1] + array[i - 2];
            }
            return array;
        }

        static int RecurseFind(int[] fullList, int[] F, int targetValue, int low, int high, int k)
        {
            if (fullList == null || fullList.Length == 0 || targetValue < fullList[low]
                || targetValue > fullList[high] || low > high)
            {
                return -1;
            }

            int mid = low + F[k - 1] - 1;
            if (targetValue < fullList[mid])
            {
                return RecurseFind(fullList, F, targetValue, low, mid - 1, k - 1);
            }
            else if (targetValue > fullList[mid])
            {
                return RecurseFind(fullList, F, targetValue, mid + 1, high, k - 2);
            }
            else
            {
                if (mid <= high)
                {
                    return mid;
                }
                return high;
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值