菜鸡笔记之——斐波那契查找
斐波那契查找:
前提:查找的序列必须已经排好序,并且数据个数为fib[k]-1个(若不足fib[k]-1个需手动扩充序列)
斐波那契查找类似于二分查找,但与二分查找不同的是分割点不同,二分查找每次以(high+low)/2作为分割点,而斐波那契查找每次以黄金分割点作为分割位置。
思路:一开始将目标值target与第F(k-1)位置的记录进行比较(即mid=low+F(k-1)),比较结果分为三种:
- 相等,mid位置的元素即为所求,直接返回mid;
- target>array[mid],low=mid+1,k-=2;
- target<array[mid],high=mid-1,k-=1;
为什么要求数据个数为fib[k]-1:
主要是为mid腾出一个位置出来,示意图如下:(图片来源为参考文章)
参考文章
代码实现(斐波那契查找)
# include <stdio.h>
# include <stdlib.h>
# define LEN 15
int main(void)
{
void creat_fib(int *,int);
int fib_search(int *,int *,int,int);
int N;
printf("the length of the array:");
scanf("%d",&N);
int * array = NULL;
array = (int *)malloc(sizeof(int)*N);
if (array==NULL)
{
printf("error!\n");
exit(-1);
}
/*enter the numbers*/
for (int i = 0;i<N;i++)
{
scanf("%d",array+i);
}
/*creat the fibonacci array*/
int fib[LEN];
creat_fib(fib,LEN);
/*search the target number*/
int target,result;
printf("which number do you want to search:");
scanf("%d",&target);
result = fib_search(fib,array,N,target);
printf("%d is the %dth number\n",target,result+1);
return 0;
}
/*
**function:creat_fib
**description:creat the fibonacci array including LEN numbers
**parameter 1: the name of the fibonacci array
**parameter 2: the length of this array
**return: none
*/
void creat_fib(int * fib,int len)
{
fib[0] = 0;
fib[1] = 1;
for (int i = 2;i<len;i++)
{
fib[i] = fib[i-1]+fib[i-2];
}
return;
}
/*
**function: fib_search
**description: finding the target number in the array by Fibonacci Search
**parameter 1: the name of fibonacci arry
**parameter 2: the name of the array
**parameter 3: the length of the array
**parameter 4: target number
**return: the place of the target in the array
*/
int fib_search(int * fib,int * array,int N,int target)
{
int low = 0,high = N-1,k = 0,mid;
/*finding the subscript of the array fib*/
while (fib[k]-1<N)
{
k++;
}
/*extend the array length to fib[k]-1*/
array = (int *)realloc(array,sizeof(int)*(fib[k]-1));
for (int i = N;i<fib[k]-1;i++)
{
array[i] = array[high];
}
/*search the target*/
while (low<=high)
{
/*mid must be base on low*/
mid = low+fib[k-1];
if (target==array[mid])
{
return (mid);
}
else if (target<array[mid])
{
high = mid-1;
k -= 1;
}
else if (target>array[mid])
{
low = mid+1;
k -= 2;
}
}
printf("can not find this number!\n");
exit(0);
}