JAVA 基本查找算法圖解 ---- 二分查找詳解

二分搜索技術

二分搜索算法是運用分治策略的典型例子。

分治分治顧名思義就是分而治之。基本思想是將一個規模比較大的問題分爲多個小問題,這些問題相互獨立且與原問題相同。遞歸的解這些問題,最後將這些問題的解進行合併得到原問題的解。下面我們以一個示例來進行介紹我們的二分搜索算法思想與代碼。

即:

1、分解

2、遞歸求解

3、合併

如:我們要在一個有序數組 [1,2,3,4,5,6,7,8,9,10,11,12,13,14]  中找尋元素值等於 9 的元素的下標,沒有則返回 -1;

先說整體思路:

(1) 分:我們首先找一箇中間元素爲基準值,將數組分爲兩份,我們選最中間下標值爲中間元素。(left +right)/2  = (0 + 13) /2= 6,即數組元素值7

      將該元素左邊的部分分作一個數組,右邊的元素分作一個數組,它自己本身爲一個數組。

      即 數組1[1,2,3,4,5,6] 、數值 [7]、 數組3 [8,9,10,11,12,13,14.]

(2)治:

       如果數值[7] 就是我們要找的數,則結束返回。

      否則我們判斷 目標值(9) > 基準值 (7),則在數組3中繼續查找。這樣我們就不需要去遍歷數組1,省去遍歷數組1 的時間,。

      重複(1)(2)步。

     直至找到目標元素或者數組遍歷結束。

我們先看下java 實現,然後如果大家還是有疑問,我們再看下面的圖解,如果你看懂了代碼,說明你已經瞭解了二分查找算法。

/**
     * 二分查找(非遞歸)
     * @param nums 目標數組
     * @param target 目標值
     * @return 目標值的下標
     */
    public static int binarySearch(int[] nums,int target){
        
        int left = 0;
        int right = nums.length -1;
        
        //(1)判斷left <= right 不滿足則 返回-1
        while(left <= right){
            //(2)找數組中間下標  mid = (left + right)/2 = 6
            int mid = (left + right)/2;
            //(3)判斷如果nums[6] == target 則返回下標 mid
            if(target == nums[mid]){
                return mid;
            }
            //(4)否則判斷 target 是否大於 num[mid]  
            //target > nums[mid] ;則 left = mid +1;
            //target < nums[mid] ;則 right = mid -1;
            if(target > nums[mid]){
                left = mid+1;
            }else {
                right = mid -1;
            }
        }
        return -1;
    }

遞歸寫法:

    /**
     * 二分查找(遞歸)
     * @param nums 數組
     * @param target 目標值
     * @param left 起始下標
     * @param right 結束下標
     * @return 目標元素的下標值 不包含目標元素返回-1
     */
    public static int binarySearch(int[] nums,int target,int left,int right){
        
       if(left > right){
           return -1;
       }
       int mid = (left + right)/2;
       if(target == nums[mid]){
           return mid;
       }
       if(target > nums[mid]){
           left = mid + 1;
       }else {
           right = mid - 1;
       }
       return binarySearch(nums,target,left,right);
    }

我們看一下圖解:

上面我們也提到了針對於均勻分佈數組的優化,代碼如下。大家自行理解下

/**
     * 插值查找
     * @param nums 數組
     * @param target 目標值
     * @return 查找結果
     */
    public static int binarySearch(int[] nums,int target){
        
        int left = 0;
        int right = nums.length -1;
        
        //(1)判斷left <= right 不滿足則 返回-1
        while(left <= right){
            
            if(left == right){
                return nums[left] == target ? left : -1;
            }
            //(2)找數組中間下標 int mid = left + (target - nums[left])/(nums[right] - nums[left])*(right - left)
            int mid = left + (target - nums[left])/(nums[right] - nums[left])*(right - left);
            //(3)判斷如果nums[6] == target 則返回下標 mid
            if(target == nums[mid]){
                return mid;
            }
            //(4)否則判斷 target 是否大於 num[mid]  
            //target > nums[mid] ;則 left = mid +1;
            //target < nums[mid] ;則 right = mid -1;
            if(target > nums[mid]){
                left = mid+1;
            }else {
                right = mid -1;
            }
        }
        return -1;
    }

歡迎大家指正以及提問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章