總結基於分治思想的乙個很簡單的演算法,但若想寫對,卻也不是那麼容易
使用條件我們l來看下邊**:二分查詢也稱折半查詢(binary search),它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列
查詢過程
/**
* 二分查詢,找到該值在陣列中的下標,否則為-1
*/int
binarysearch
(int
*a,int asize ,
int key)
return-1
;}
(1)處:,如果是"<"的話,low==high事程式就退出了,處於該位置的元素顯然就被遺漏了。
(2)處:這是乙個很著名的bug!
我們知道,數學中數有無窮大,那麼求其平均數,相加除以二顯然不會有任何的問題。但是在計算機中,所有的數都是以二進位制的形式儲存在記憶體中的,記憶體有限,所以儲存的數自然不可能無窮大。
比如int型資料,現在一般是32位,第一位做符號位,所以它的範圍[-231,231-1],如果low+high超過了231-1那麼就溢位了,顯然結果就不對了。而用我們能這種方法,便可以保證不會有溢位的風險。
二分查詢變種主要有以下幾種:
查詢 第乙個/最後乙個 與key相等的元素首先,對於這些變種的程式,總會有如下共性:查詢最後乙個等於或者小於key的元素
查詢最後乙個小於key的元素
查詢第乙個等於或者大於key的元素
查詢第乙個大於key的元素
不變性:查詢第乙個與key相等的元素1.迴圈永遠是low>high時才跳出
2
if(a[mid]>key) high=mid-1;
.3.
if(a[mid]所以,對於每個變種,我們需要考慮的情況:
1.a[mid]==key這種情況的處理
2.最後的結果儲存在low中還是high中
因為我們要找的是第乙個(從左至右),所以當遇到 a[mid]==key 的情況時,肯定不能讓 low=mid+1,否則就錯過了第乙個啦,那麼只能讓 high=mid-1 嘍!
當然,我們再正面分析一下:
if上述**迴圈執行到最後,high指標所指向的元素一定是據key最近的小於key的元素;(a[mid]
>=key)
high = mid -1;
//為了破壞if中的條件
if
(a[mid]
low=mid+1;
//為了破壞if中的條件
上述**迴圈執行到最後,low指標所指向的元素一定是大於等於key這些元素中的第乙個元素(從左至右)。
非正式的驗證了演算法的正確性,而且知道了最後的結果儲存在low中.
以下是完整**:
int
binarysearch
(int
*a,int asize ,
int key)
if(low < asize && a[low]
==key)
//注意這裡應該防止low溢位
return low;
return-1
;}
查詢最後乙個與key相等的元素
因為要找最後乙個,所以第一次遇到 a[mid]==key 時,應該選擇low=mid+1;
迴圈破壞 a[mid]<=key 後,low所指元素為大於key的第乙個元素;
迴圈破壞 a[mid]>key 後,high為小於等於key的最大序號。所以,最後的結果儲存在high中。
完整**如下:
int
binarysearch
(int
*a,int asize ,
int key)
if(high >=
0&& a[high]
==key)
//注意這裡應該防止high溢位
return high;
return-1
;
查詢最後乙個等於或者小於key的元素
就是查詢最後乙個與key相等的元素中的high,分析同上,**如下:
int
binarysearch
(int
*a,int asize ,
int key)
return high;
查詢最後乙個小於key的元素
就是查詢第乙個與key相等的元素的high,分析同上,**如下:
int
binarysearch
(int
*a,int asize ,
int key)
return high;
}
查詢第乙個等於或者大於key的元素:
此情況其實與上邊的分析差不多,就不多寫廢話啦。**如下:
int
binarysearch
(int
*a,int asize ,
int key)
return low;
}
查詢第乙個大於key的元素
此情況其實與上邊的分析差不多,就不多寫廢話啦。**如下:
int
binarysearch
(int
*a,int asize ,
int key)
return low;
}
step1.對於所有二分,下邊兩個條件都是必須的,所以我們只需分析 a[mid]==key 應該給high還是low。
1if(a[mid]>key) high=mid-1;
.
2.if(a[mid]step2.判斷輸出結果,最普通的二分查詢直接return;其他變種可能在low中,也可能在high中,利用上述我所說 迴圈的目的是為了破壞if條件句中的條件,然後該語句的否定,再加上減一這個條件,即可推出low和 high所存序號的意義。
參考:你真的會寫二分查詢嗎
如何寫好乙個二分搜尋
最近寫了乙個二分搜尋,結果不盡人意,總是出錯。所以翻了一些部落格,看到一些關於使用迴圈不變體的方法來寫二分搜尋。如何寫出正確的二分搜尋 我就寫好乙個二分搜尋進行了一下總結 確定你這個二分的目的,以下會舉7個例子說一下常用的求解target 確定條件,就三個,s mid 確定迴圈的條件 while l...
教你如何寫出乙個碎片輪播
對於幾乎每乙個入行前端的小夥伴來說,輪播圖幾乎都是必修課,但是,只是單純的切換過渡可能並不能滿足於你追求酷炫的心hh,那麼這裡就教你利用css3的clip path來模擬碎片並為你的輪播圖新增碎片輪播的效果!對於一張來說,如果在原有的基礎上新增一層蒙版,遮蔽住不想讓使用者見到的檢視,剩下的檢視即可作...
乙個二分查詢程式
原問題來自 http topic.csdn.net u 20090826 18 c08b69e8 ce22 4427 8687 ffb53e380437.html 問題如下 有一連串字母,由且必由若干個 a,b,c,d,e 組成,順序是 若干個 a,若干個 b,若干個 c,若干個 d,若干個 e 即...