Fibonacci 數(shù)列
Fibonacci 數(shù)列,又稱黃金分割數(shù)列,指的是這樣一個(gè)數(shù)列:
1 1 2 3 5 8 13 21 ····
數(shù)學(xué)上吱瘩,F(xiàn)ibonacci 數(shù)列遞歸定義:
F(1)=1阳柔,F(xiàn)(2)=1,F(xiàn)(n) = f(n-1) + F(n-2) (n>=2)
該數(shù)列越往后相鄰的兩個(gè)數(shù)的比值越趨向于黃金比例值(0.618)
Fibonacci 查找
- 構(gòu)建 Fibonacci 數(shù)列
- 擴(kuò)展數(shù)組 a告匠,用 a[n-1] 填充后面的數(shù)組
- mid = F[k-1] - 1蛛倦,比較 temp[mid] 與 key
- key < temp[mid]耻煤,落在前半部分晾匠,k -= 1茶袒,待查找的數(shù)列長(zhǎng)度變?yōu)?F[k-1]
- key > temp[mid],落在后半部分凉馆,k -= 2薪寓,待查找的數(shù)列長(zhǎng)度變?yōu)?F[k-2]
- key = temp[mid],比較 mid 與 n句喜,mid >= n 說明落在擴(kuò)展的數(shù)列上预愤,返回 n-1
與二分查找的區(qū)別
- 二分查找與 key 比較的數(shù)的下標(biāo): (left + right) / 2
- Fibonacci 查找與 key 比較的數(shù)的下標(biāo) F[k] - 1,都是 fibonacci 數(shù)列上的
因?yàn)?F[k] 表示元素個(gè)數(shù)咳胃,-1 之后才表示下標(biāo)
#include <iostream>
using namespace std;
#define MAX_SIZE 20 // 斐波那契數(shù)組的長(zhǎng)度植康,4181足夠了
/**
* 斐波那契查找
* @param a: 要查找的數(shù)組
* @param n: 數(shù)組 a 的長(zhǎng)度
* @param key: 要查找的關(guān)鍵字
* @return 要查找的 key 在數(shù)組中的下標(biāo)
*/
int fibonacciSearch(const int *a, int n, int key) {
// 構(gòu)建 Fibonacci 數(shù)列 F
int F[MAX_SIZE];
F[0] = 0;
F[1] = 1;
for (int i = 2; i < MAX_SIZE; ++i)
F[i] = F[i - 1] + F[i - 2];
// 在數(shù)列中尋找合適的數(shù)組長(zhǎng)度 F[k]等于或剛剛大于n
int k = 2;
while (n > F[k]) ++k;
// 擴(kuò)展數(shù)組a,并用 a[n-1] 填充后面的數(shù)組
int temp[F[k]];
for (int i = 0; i < n; ++i) temp[i] = a[i];
for (int i = n; i < F[k]; ++i) temp[i] = a[n - 1];
// 查找
int low = 0;
int high = n - 1;
while (low <= high) {
int mid = low + F[k - 1] - 1; // 第F[k - 1]個(gè)數(shù)的下標(biāo)
if (key < temp[mid]) { // 左邊
high = mid - 1;
k -= 1; // F[k-1]是前半部分?jǐn)?shù)組長(zhǎng)度
} else if (key > temp[mid]) { // 右邊
low = mid + 1;
k -= 2; // F[k-2]是后半部分?jǐn)?shù)組長(zhǎng)度
} else { // 相等展懈,判斷 mid 位置
if (mid < n)
return mid;
else
return n - 1;
}
}
return -1;
}
void printArray(const int *a, int len) {
for (int i = 0; i < len; ++i) {
cout << a[i] << " ";
}
cout << endl;
}
int main() {
int a[10] = {0, 16, 24, 35, 47, 59, 62, 73, 88, 99};
printArray(a, 10);
cout << "查找:";
int key;
cin >> key;
cout << "位置:" << fibonacciSearch(a, 10, key);
return 0;
}
0 16 24 35 47 59 62 73 88 99
查找:47
位置:4