1. 程式人生 > >折半查詢和差值查詢

折半查詢和差值查詢

都用於有序陣列,下面假設單增
折半查詢思想簡單,直接寫了

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; }