在這裏總結一下幾個基於有序的查找算法,理解也不是很透徹,自己感受一下!
1.折半查找:又稱二分查找,前提是數據有序,通常是從下到大有序,且必須採用順序存儲。
思想:在有序表中,取中間值進行第一次比較,要是要查找的值key==a[mid] ,則查找成功,返回中間值小於要查找的值,所用要查找的在右邊部分,則在右邊繼續找中間值一次次的比較,知道找到這個值。
這個思想非常好理解,就像平時我們猜數字遊戲,1-100之間讓你猜是哪個數,你第一次一定會猜50 ,我說大了,第二次你改在0-50猜,你說25,我說小了,你就會在25--50猜。
折半查找就是基於這個思想。
<span style="font-family:KaiTi_GB2312;font-size:14px;">int Binary_Search(int *a,int n,int key) {
int low,high,mid;
low = 1;
high = n;
while(low<=high) {
mid = (low+high)/2;
if(key < mid)
high = mid +1;
else if(key>mid)
low = mid +1;
else
return mid;
}
return 0;
}
</span>
折半算法的時間複雜度O(logn)
2.插值查找:這個的思想是:1--1000之間100個元素從小到大均勻分佈,要查找的key=5,這時你會在分段爲50 的話是不是同樣很費時。
所以就有了插值查找:思想是根據要查的關鍵字key與查找表中最大最小記錄的關鍵字比較後的查找方法,其核心在於插值的計算公式爲:
key-a[low]/a[high]-a[low].
雖然時間複雜度也是O(logn)
但是當對於表比較長,而且分佈均勻的表來說,性能比較好。
Eg:a[11] = {0,1,16,24,35,47,59,62,73,88,99}.low = 1,hign=10 key =16,
則用折半查找需要四次
用本方法:key-a[low]/a[high]-a[low] =0.153 即mid = 1+0.153*(10-1)=2.377
所以此時mid= 2,也就是我們只需兩次就好了。
算法呢和折半幾乎沒有差別,唯一的不同便是mid的定位不一樣。
mid = 1+(key-a[low])/(a[high]-a[low])*(high - low);
3.斐波那契查找:利用的是黃金分割的原理來實現的。但是在使用時我們要用一個斐波那契數組。
代碼:
老實說這個我也不太理解要這麼做的好處是什麼,感覺這個比插值查找難理解,還多了空間複雜度,但是就是有這麼一個啦!
代碼不好理解,但是好走,帶數值走一遍會理解深一點
<span style="font-family:KaiTi_GB2312;font-size:14px;"> int Fibonacci_Search(int *a,int n,int key) {
int low,high,mid,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;
k=k-1;
}
else if(key>mid) {
low = mid +1;
k = k-2;
}
else
if(mid<n)
return mid;
else
return n;
}
return 0;
}</span>