二分查找又稱折半查找,優點是比較次數少,查找速度快,平均性能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查找方法適用於不經常變動而查找頻繁的有序列表。首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查找關鍵字比較,如果兩者相等,則查找成功;否則利用中間位置記錄將表分成前、后兩個子表,如果中間位置記錄的關鍵字大於查找關鍵字,則進一步查找前一子表,否則進一步查找后一子表。重復以上過程,直到找到滿足條件的記錄,使查找成功,或直到子表不存在為止,此時查找不成功。
Bentley在他的著作《Writing Correct Programs》中寫道,90%的計算機專家不能在2小時內寫出完全正確的二分搜索算法。問題的關鍵在於准確地制定各次查找范圍的邊界以及終止條件的確定,正確地歸納奇偶數的各種情況,其實整理后可以發現它的具體算法是很直觀的。
折半查找法的優點是比較次數少,查找速度快,平均性能好; 其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查找方法適用於不經常變動而查找頻繁的有序列表。
算法步驟描述
① 首先確定整個查找區間的中間位置 mid = ( left + right )/ 2
② 用待查關鍵字值與中間位置的關鍵字值進行比較;
若相等,則查找成功
若大於,則在后(右)半個區域繼續進行折半查找
若小於,則在前(左)半個區域繼續進行折半查找
③ 對確定的縮小區域再按折半公式,重復上述步驟。
最后,得到結果:要么查找成功, 要么查找失敗。折半查找的存儲結構采用一維數組存放。
折半查找算法舉例
對給定數列(有序){ 3,5,11,17,21,23,28,30,32,50,64,78,81,95,101},按折半查找算法,查找關鍵字值為81的數據元素。
折半查找的算法討論:
優點:
ASL≤log2n,即每經過一次比較,查找范圍就縮小一半。經log2n 次計較就可以完成查找過程。
缺點:
因要求有序,所以要求查找數列必須有序,而對所有數據元素按大小排序是非常費時的操作。另外,順序存儲結構的插入、刪除操作不便利。
考慮:
能否通過一次比較拋棄更多的部分(即經過一次比較,使查找范圍縮得更小),以達到提高效率的目的。……?
可以考慮把兩種方法(順序查找和折半查找)結合起來,即取順序查找簡單和折半查找高效之所長,來達到提高效率的目的?實際上這就是分塊查找的算法思想。
Arrays提供的二分查找功能:
binarySearch()方法的返回值為:
1、如果找到關鍵字,則返回值為關鍵字在數組中的位置索引,且索引從0開始
2、如果沒有找到關鍵字,返回值為負的插入點值,所謂插入點值就是第一個比關鍵字大的元素在數組中的位置索引,而且這個位置索引從1開始。
public static void main(String[] args) { int[] arr = {1,3,5,6,4,7,12,25,13}; System.out.println(Arrays.toString(arr)); //使用二分查找功能,必須先排序 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); int num = Arrays.binarySearch(arr,12); System.out.print(num); }