數據結構之--斐波那契查找
定義:相當於折半查找,一般將帶比較的key值與第mid=(low+high)/2位置的元素比較,比較結果分為三種情況:
1),相等,mid位置的元素即為所求;
2),>,low=mid+1;
3),<,high=mid-1;
跟折半查找很相似,它是根據斐波那契數列的特點對有序表進行黃金分割。
圖解:
時間復雜度:如果要查找的記錄在右側,則左邊的數據都不用在哦按段了,不斷反復進行下去,對處於當中的大部分數據源,其工作效率要高一些所以盡管斐波那契查找的時間復雜度也為O(logn)。但品均性能上來說,斐波那契查找要優於折半查找,可惜如果是最壞情況,比如這里key=1的時候,那么始終都處於左側長半區在查找,則查找效率要低於折半查找。
還有一點比較關鍵,折半查找是進行假發與除法運算(mid={low+high}/2),插值查找進行復雜的四則運算(mid=low+(high-low)*(key-a[low])/(a[high]-a[low])),而斐波那契額查找只是最簡單加減運算(mid=low+F[k-1]-1),在海量數據的查找過程中,這種細微的差別可能會影響最終的查找效率。
應該說“順序表查找”、“折半查找”、“插值查找”這三種查找本質上是分隔點不同,各有優劣,實際開發過程中可根據實際情況中數據的綜合特點再做出選擇。
#include<stdio.h>
int F[] = {0,1,1,2,3,5,8,13,21,34,55};
int Binary_Search(int *a,int n,int key){
int low,mid,high,i,k;
low = 1; /*定義最低下表為記錄首位*/
high = n; /*定義最高下表為記錄末位*/
k = 0;
while(n>F[k]-1) /*計算n位於斐波那契數列的位置*/
k++;
for(i=n;i<F[k]-1;i++) /*將不滿的數值補全*/
a[i]=a[n];
while(low<=high){
mid=low+F[k-1]-1; /*計算當前分隔的下標*/
if(key<a[mid]){ /*若查找記錄小於當前分隔記錄*/
high=mid-1; /*最高下標調整到分隔下標mid-1處*/
k--;
}
else if(key>a[mid]){ /*斐波那契數列下標減一位*/
low=mid+1; /*最低下標調整到分隔下標mid+1處*/
k=k-2; /*斐波那契數列下標減兩位*/
}
else{
if(mid<=n)
return mid; /*若相等則說明mid即為查找到的位置*/
else
return n; /*若mid>n說明是不全數值,返回n*/
}
}
return 0;
}
void main(){
int num[] = {0,1,26,24,35,47,59,62,73,88,99};
int result = Binary_Search(num,sizeof(num)/sizeof(num[0])-1,62);
printf("'斐波那契查找'結果為:%d\n",result);
}