斐波那契查找
在介绍斐波那契查找算法之前,我们先介绍一下很它紧密相连并且大家都熟知的一个概念——黄金分割。
黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。
0.618被公认为最具有审美意义的比例数字,这个数值的作用不仅仅体现在诸如绘画、雕塑、音乐、建筑等艺术领域,而且在管理、工程设计等方面也有着不可忽视的作用。因此被称为黄金分割。
大家记不记得斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和)。然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中。
1)相等,mid位置的元素即为所求
2)>,low=mid+1;
3)<,high=mid-1。
斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;
开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种
1)相等,mid位置的元素即为所求
2)>,low=mid+1,k-=2;
说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。
3)<,high=mid-1,k-=1。
说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。
C++实现源码:
1 //斐波那契查找 2 #include <iostream> 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <cstring> 6 #include <ctime> 7 8 using namespace std; 9 10 #define MAX 100 11 #define max_size 150 12 13 //数组输入 14 void input(int *arr) 15 { 16 srand((unsigned)time(NULL)); 17 for(int i = 0; i < MAX; i++) 18 { 19 arr[i] = rand()%100; 20 } 21 } 22 //数组输出 23 void output(int *arr) 24 { 25 for(int i = 0; i < MAX; i++) 26 { 27 printf("%5d", arr[i]); 28 if(0 == (i+1) % 10) 29 cout << endl; 30 } 31 cout << endl; 32 } 33 //快速排序 34 void quickSort(int *arr, int l, int h) 35 { 36 if(l < h) 37 { 38 int low, high, tmp; 39 low = l; 40 high = h; 41 42 tmp = arr[l];//选择基准值 43 //将数组按照基准值分为两部分 44 while(low < high) 45 { 46 while(low < high && arr[high] > tmp) 47 high--; 48 if(low < high) 49 arr[low++] = arr[high]; 50 while(low < high && arr[low] < tmp) 51 low++; 52 if(low < high) 53 arr[high--] = arr[low]; 54 } 55 arr[low] = tmp; 56 //递归排序 57 quickSort(arr, l, low-1); 58 quickSort(arr, low+1, h); 59 } 60 } 61 //构造一个斐波那契数组 62 void fibonacci(int * F) 63 { 64 F[0] = 0; 65 F[1] = 1; 66 for(int i = 2; i < max_size; i++) 67 F[i] = F[i-1] + F[i-2]; 68 } 69 //斐波那契查找 70 int fibonacciSearch(int *arr, int len, int value) 71 { 72 int low = 0; 73 int high = len-1; 74 75 int F[max_size]; 76 fibonacci(F);//构造一个斐波那契数组 77 78 int k = 0; 79 while(len > F[k]-1)//计算n位于斐波那契数组中的位置 80 k++; 81 82 int *temp;//将数组arr扩展到F[k]-1长度 83 84 temp=new int [F[k]-1]; 85 memcpy(temp, arr, len*sizeof(int)); 86 87 for(int i = len; i < F[k]-1; i++) 88 temp[i] = arr[len-1]; 89 90 while(low < high) 91 { 92 int mid = low + F[k-1]-1; 93 if(value < temp[mid]) 94 { 95 high = mid -1; 96 k -= 1; 97 } 98 else if(value > temp[mid]) 99 { 100 low = mid+1; 101 k -= 2; 102 } 103 else 104 { 105 if(mid < len) 106 return mid; 107 else 108 return len-1; 109 } 110 } 111 delete[] temp; 112 return -1; 113 } 114 115 116 int main() 117 { 118 int x, pos, num[MAX]; 119 input(num); 120 121 cout << "sort before:" << endl; 122 output(num); 123 quickSort(num, 0, MAX-1); 124 cout << "sort after:" << endl; 125 output(num); 126 127 cout << "Enter find num : "; 128 cin >> x; 129 130 pos = fibonacciSearch(num, MAX, x); 131 if(pos) 132 cout << "OK!" << x << "is found in pos : " << pos << endl; 133 else 134 cout << "Sorry!" << x << "is not found in num" << endl; 135 136 return 0; 137 }