折半查詢和差值查詢
阿新 • • 發佈:2018-12-09
都用於有序陣列,下面假設單增
折半查詢思想簡單,直接寫了
public static int BinarySearch(int a[],int k)
{
int l=0;
int r=a.length-1;
while(l<=r)
{
int m=(l+r)/2;
if(a[m]==k) return m;
else if(k<a[m]) r=m-1;
else l=m+1;
}
return -1;
}
再介紹一下二路比較的折半插入,就像你猜數,問別人大了還是沒大,別人只能回答是或否。
public static int do_it(int a[],int k)
{
int l=0;
int r=a.length-1;
while(l<r)
{
int m=(l+r)/2;
if(k<=a[m]) r=m;
else l=m+1;
}
if(a[l]==k) return l;
else return -1;
}
插值查詢
假設這個單增陣列滿足線性,我們可以由兩頭的座標以及現在的值來求下標,如圖
插值查詢實際上是利用了陣列本身的特徵,在沒有特徵的時候,假設陣列是線性增長的。
如果真的有特徵(線性、二次等),而不是假設的線性增長,估計插值查詢效果會好些。
Robert Sedgewick認為較小的檔案,折半查詢可能更好,但對於更大的檔案和比較的開銷大訪問的成本高的應用,插值查詢可能更好。
下面是程式碼,rate<0或rate>1說明超出範圍
public static int Interpolation_Search(int a[],int v)
{
int l=0;
int r=a.length-1;
while(l<=r)
{
if(a[l]==a[r])//避免下面出現除數為0
{
if(v==a[l]) return l;
else return -1;
}
else
{
double rate=((double)(v-a[l]))/(a[r]-a[l]);
if (rate<0||rate>1)
return -1;//rate<0越過左邊,rate>0越過右邊
int x=l+(int)((r-l)*rate);
if(v==a[x]) return x;
else if(v<a[x]) r=x-1;
else l=x+1;
}
}
return -1;
}