1. 程式人生 > >演算法(第4版) 學習筆記二——二分查詢的普通實現與遞迴實現

演算法(第4版) 學習筆記二——二分查詢的普通實現與遞迴實現

以查詢某個特定元素在已排序陣列中的索引為例,且此陣列為從小到大排序。

演算法思路:

1、取第一個索引和最後一個索引代表兩個遊標,一個lo,一個hi
2、取lo和hi的中間值,即為mid,如下圖所示,中間值為4
這裡寫圖片描述
3、取出中間索引處的值,與輸入值i比較

  • 假如比i大,那麼說明我們要的值在上面,把hi值變成剛剛取的中間索引值,即hi=mid-1,lo值保持不變,
  • 假如比i小,那麼說明我們要的值在下面,把lo值變成剛剛取得中間索引值,即lo=mid+1,hi值保持不變
  • 假如兩個值相等,那麼返回mid

注1:為什麼需要mid減1或加1?

4、重複2~3步,直到lo>hi

注2:為什麼是>而不是>=?

普通實現:

public static int indexOf(int i, int[] a) {
    int lo = 0;//定義上索引
    int hi = a.length - 1;//定義下索引
    while(lo<=hi) {
        int mid = (lo + hi) / 2;
        if(a[mid]>i) hi = mid - 1;//假如比i大
        else if(a[mid]<i) lo = mid + 1;//假如比i小
        else return mid;
    }
    return
-1;//沒找到 }

遞迴實現:

public static int indexOf(int i, int[] a) {
    indexOf(i, a, 0, a.length-1);
}
public static int indexOf(int i, int[] a, int lo, int hi) {
    if(lo>hi) return -1;
    int mid = (lo + hi) / 2;
    if(a[mid]>i) return indexOf(i, a, lo, mid-1);
    else if(a[mid]<i) return indexOf(i, a, mid+1
, hi); return mid; }

注1解答:因為mid已經不滿足條件,我們已經不需要它了

注2解答:因為在=出現的時候,mid = lo = hi,而這個mid值是上一步的mid減1或加1得到的,即這兩個mid不可能相等,為了驗證最後的這個mid是不是我們需要的mid,所以還需要這兩個值相等,而下一步要麼是lo = mid + 1 > hi,要麼是hi = mid - 1 < lo,都會不滿足lo<=hi的條件而跳出迴圈