C Fibonacci Search

Summary: in this tutorial, you will learn how to implement Fibonacci search algorithm in C.

The Fibonacci search allows you to search a sorted array. The Fibonacci search technique uses a divide-and-conquer mechanism that helps decrease the possible locations by using Fibonacci numbers.

The following is the Fibonacci search program in C:

#include <stdio.h> #include <stdlib.h> #include <limits.h> /* * If val is found in arr, return the index of its location in arr. * Otherwise, return the index of the smallest element greater than val */ static int binsrch_geq(const int *arr, int n, int val) { register int low, high, mid; int geq; low=0; high=n-1; geq=-1; /* binary search for finding the element with value val */ while(low<=high) { mid=(low+high)>>1; //(low+high)/2; if(val<arr[mid]) { high=mid-1; geq=mid; } else if(val > arr[mid]) low=mid+1; else return mid; /* found */ } return geq; /* not found */ } /* Fibonaccian search for locating the index of "val" in an array "arr" of size "n" that is sorted in ascending order. Algorithm description ----------------------------------------------------------------------------- Let Fk represent the k-th Fibonacci number where Fk+2=Fk+1 + Fk for k>=0 and F0 = 0, F1 = 1. To test whether an item is in a list of n = Fm ordered numbers, proceed as follows: a) Set k = m. b) If k = 0, finish - no match. c) Test item against entry in position Fk-1. d) If match, finish. e) If item is less than entry Fk-1, discard entries from positions Fk-1 + 1 to n. Set k = k - 1 and go to b). f) If item is greater than entry Fk-1, discard entries from positions 1 to Fk-1. Renumber remaining entries from 1 to Fk-2, set k = k - 2 and go to b) If Fm>n then the original array is augmented with Fm-n numbers larger than val and the above algorithm is applied. */ int fibsrch(const int *arr, int n, int val) { register int k, idx, offs; static int prevn=-1, prevk=-1; /* Precomputed Fibonacci numbers F0 up to F46. This implementation assumes that the size n * of the input array fits in 4 bytes. Note that F46=1836311903 is the largest Fibonacci * number that is less or equal to the 4-byte INT_MAX (=2147483647). The next Fibonacci * number, i.e. F47, is 2971215073 and is larger than INT_MAX, implying that it does not * fit in a 4 byte integer. Note also that the last array element is INT_MAX rather than * F47. This ensures correct operation for n>F46. */ const static int Fib[47+1]= {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, INT_MAX }; /* find the smallest fibonacci number that is greater or equal to n. Store this * number to avoid recomputing it in the case of repetitive searches with identical n. */ if(n!=prevn) { #if 1 k=(n>1)? binsrch_geq(Fib, sizeof(Fib)/sizeof(int), n) : 1; #else /* the above binary search call can be substituted by the following code fragment: */ { register int f0, f1, t; for(f0=0, f1=1, k=1; f1<n; t=f1, f1+=f0, f0=t, ++k) ; } #endif prevk=k; prevn=n; } else k=prevk; /* If the sought value is larger than the largest Fibonacci number less than n, * care must be taken top ensure that we do not attempt to read beyond the end * of the array. If we do need to do this, we pretend that the array is padded * with elements larger than the sought value. */ for(offs=0; k>0; ) { idx=offs+Fib[--k]; /* note that at this point k has already been decremented once */ if(idx>=n || val<arr[idx]) // index out of bounds or val in 1st part continue; else if (val >arr[idx]) // val in 2nd part { offs=idx; --k; } else // val==arr[idx], found return idx; } return -1; // not found } int main() { int data[]= {1, 4, 5, 7, 9, 11, 13, 16, 18, 20, 25, 27, 30, 32, 33, 36, 39, 41, 44, 47, 51, 53, 55}; int i, x, n; x = 30; n = sizeof(data)/sizeof(int); i = fibsrch(data, n, x); if(i>=0) printf("%d found at index %d\n", x, i); else printf("%d was not found\n", x); return 0; }
Code language: C++ (cpp)
Was this tutorial helpful ?