學習更多演算法系列請參考文章:死磕演算法之彙總篇
二分查詢又稱折半演算法,此演算法作為一個經典的查詢演算法是我們不得不掌握的演算法
這個演算法查詢的前提是查詢的資料是有序的,我們以陣列為例,使用二分查詢法進行查詢的時候我們應該先定義三個欄位:
1.left指向陣列第一個資料
2.right指向陣列最後一個元素
3.mid呢指向(left+right)/2位置的元素,就是他們中間的位置。
當我們要在一個陣列中查詢一條資料a時,有這麼幾個步驟:
- 首先我們拿a與mid比較,如果a與mid相等那麼我們就成功找到了這個資料,程式停止。
- 如果a比mid小進行第3步,如果a比mid大進行第4步
- 既然a小於mid,那麼mid與right之間的數肯定比a大,所以我們忽略它們,緊接著把right指向mid的前一個位置。(你可能會問為啥指向前一個位置不指向mid呀,因為我們已經確定了mid不等於a,那麼我們就不需要在比較他了)
- 既然a大於mid,那麼mid與left之間的數肯定比a小,所以我們忽略它們,緊接著把left指向mid的後一個位置。(不明白可以參考3哦)
- 如果left不大於right那麼我們就還沒有查詢完畢,繼續進行第一步。如果left已經大於了right,那麼就代表在這個陣列裡我們沒有找到想要的資料。
建議對二分查詢不太熟悉的同學可以先在草稿紙上、電腦上或者腦海裡定義一個0-16的有序陣列跟著上邊的步驟來查詢一下資料5。
下面這個圖是我畫的圖,來看一下跟你畫的步驟或者想象的步驟一樣麼
如果上圖你已經看明白了的話那麼接下來我們就上程式碼吧,
public static void select(int[]num,int a){
int left=0;
int right=num.length-1;
int m=(left+right)/2;
while(left<=right){
if(num[m]==a){
System.out.println("在"+m+"位置找到");
return;
}
if (num[m]>a){
right=m-1;
}else{
left=m+1;
}
m=(left+right)/2;
}
System.out.println("沒找到");
}
複製程式碼
上面的方法使用了一個普通的迴圈的方式,二分還存在一種遞迴的寫法,這裡也分享出來
public static void select(int[]num,int a,int left,int right){
if(left>right){
System.out.println("沒找到");
return;
}
int m=(left+right)/2;
if(num[m]==a){
System.out.println("在"+m+"位置找到");
return;
}
if (num[m]>a){
right=m-1;
select(num, a,left,right);
}else{
left=m+1;
select(num, a,left,right);
}
}
複製程式碼
二分查詢法講到這裡已經講完了。在這裡溫馨提示大家,學習演算法時,我們沒必要拘泥於程式碼的實現,那沒有意義。我的建議就是深入理解步驟,當你理解步驟以後程式碼是隨你怎麼玩都可以的。