死磕演算法之二分查詢法

Java學習錄發表於2018-06-29

學習更多演算法系列請參考文章:死磕演算法之彙總篇


二分查詢又稱折半演算法,此演算法作為一個經典的查詢演算法是我們不得不掌握的演算法

這個演算法查詢的前提是查詢的資料是有序的,我們以陣列為例,使用二分查詢法進行查詢的時候我們應該先定義三個欄位:

1.left指向陣列第一個資料

2.right指向陣列最後一個元素

3.mid呢指向(left+right)/2位置的元素,就是他們中間的位置。


當我們要在一個陣列中查詢一條資料a時,有這麼幾個步驟:

  1. 首先我們拿a與mid比較,如果a與mid相等那麼我們就成功找到了這個資料,程式停止。
  2. 如果a比mid小進行第3步,如果a比mid大進行第4步
  3. 既然a小於mid,那麼mid與right之間的數肯定比a大,所以我們忽略它們,緊接著把right指向mid的前一個位置。(你可能會問為啥指向前一個位置不指向mid呀,因為我們已經確定了mid不等於a,那麼我們就不需要在比較他了)
  4. 既然a大於mid,那麼mid與left之間的數肯定比a小,所以我們忽略它們,緊接著把left指向mid的後一個位置。(不明白可以參考3哦)
  5. 如果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);
        }
}

複製程式碼

二分查詢法講到這裡已經講完了。在這裡溫馨提示大家,學習演算法時,我們沒必要拘泥於程式碼的實現,那沒有意義。我的建議就是深入理解步驟,當你理解步驟以後程式碼是隨你怎麼玩都可以的。



相關文章