java實現二分查找(二分搜索)

二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。
使用二分查找的數據必須是有序的,數據結構一般是數組。
實現思想:

  • 1 拿想要搜索的數去和有序數組的中位數比較,如果相等的話,就找到了。
  • 2 如果中位數比較大,則從中位數左邊那一塊範圍繼續找,右邊的不用找了。找左邊的時候繼續與左邊那一塊的中位數比較。
  • 3 如果中位數比較小,則從中位數右邊那一塊範圍繼續找,左邊的不用找了。找右邊的時候繼續與右邊那一塊的中位數比較。
  • 4 重複123步,不斷地縮小範圍,直到找到爲止(即中位數等於要搜索的數),如果查找過程中出現左邊界的下標大於右邊界的下標,則說明數組中沒有要搜索的數。

類似的簡單例子:
張三買了一本30元的《算法入門到放棄》,讓李四從1-100之間猜書的價格(只能猜整數),張三不斷提示猜對了,或者是猜多了還是猜少了。
如果李四從1,2,3,4 ···開始猜,則要猜30次。如果從100, 99 , 98 ···開始猜,則要猜71次。但是李四很聰明,他是這樣猜的。

李四:50。
張三:不對,猜多了。
李四心想:“搜嘎,那就是在1-50之間咯~,哦不對,是1-49,再猜一箇中間的數”。
李四:25。
張三:不對哦,你猜少了。
李四:(那就是在25-49之間,不,是26-49之間),是37嗎?
張三:不是,猜多了。
李四:31?
張三:猜多了。
李四:28?
張三:猜少了。
李四:29?
張三:猜少了。
李四:知道了,30塊,哈哈。
張三:恭喜你,猜對啦。

由以上可知,聰明的李四用二分查找的思想,猜了7次就猜對了。

下面是java實現二分查找的代碼:

/*
*二分查找算法
* 使用條件:已經排好序的數組
* */

public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,10,11,12,23,34,56,78,89};//示例數組
        int target = 10;   							 //搜索目標數
        int result  = binarySearch(arr, target);	 //調用搜索方法
        System.out.println(result);
    }
    private static int binarySearch(int[] arr, int target){
        int l = 0;                  //左邊界
        int r = arr.length-1;       //右邊界爲數組長度-1
        int mid = l + (r - l) / 2;  //有序數組的中位數,也可以寫成  mid = (r + l) / 2
        while (arr[mid] != target){ //中位數不等於目標數
            if (arr[mid] > target){
                r = mid - 1;        //目標在中位數的左側,縮小範圍
            }
            else {
                l = mid + 1;        //目標在中位數的右側,縮小範圍
            }
            if (l > r){
                return -1;			//搜索失敗,搜索範圍不斷縮小過程中,左邊界大於右邊界
            }
            //System.out.println(arr[l] + "  " + arr[r]); //取消註釋可以查看每一次搜索時的查找範圍
            mid = l + (r - l) / 2;
        }
        return arr[mid];            //搜索成功,返回搜索到的數
    }
}

對於算法而言,解決問題的思想是精髓,語言不過是實現的工具而已,如果掌握了思想,趕快用自己熟悉的編程語言去試一試吧。

使用遞歸的方法也可以實現。
只是不太建議,當數組大的時候內存佔用會比較多。

public class BinarySearch2 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,10,11,12,23,34,56,78,89};
        int target = 19;    //搜索目標數
        int l = 0;                  //左邊界
        int r = arr.length-1;       //右邊界爲數組長度-1
        binarySearch(arr, l, r, target);//調用搜索函數
    }
    private static void binarySearch(int[] arr,int l, int r, int target){
        int mid = l + (r - l) / 2;  //有序數組的中位數
        if (arr[mid] != target){ //中位數不等於目標數
            if (arr[mid] > target){
                r = mid - 1;        //目標在中位數的左側,縮小範圍
            }
            else {
                l = mid + 1;        //目標在中位數的右側,縮小範圍
            }
            if (l > r){
                System.out.println("fail to find the target");
                return ;//搜索失敗,搜索範圍不斷縮小過程中,左邊界大於右邊界
            }
//            System.out.println(arr[l] + "  " + arr[r]); //取消註釋可以查看每一次搜索時的查找範圍
            binarySearch(arr, l, r, target);			  //遞歸調用
            return ;
        }
        System.out.println("success! " + arr[mid]);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章