二分搜索算法代碼實現


 

 

/**
 * 二分搜索算法(包含遞歸與非遞歸)
 */
public class BinarySearch {

    public static void main(String[] args) {

//        int[] nums = {1, 3, 5, 6, 8, 9, 11};
//        int i = binarySearch2(nums, 11, 0, nums.length - 1);

//        int[] nums = {5, 7, 7, 8, 8, 10};
//        int i = searchLowerBound(nums, 8, 0, nums.length - 1);
//        int j = searchUpperBound(nums, 8, 0, nums.length - 1);

//        int[] nums = {-2, 0, 1, 4, 7, 9, 10};
//        int i = firstGreaterThan(nums, 6, 0, nums.length - 1);

        int[] nums = {4, 5, 6, 7, 0, 1, 2}; //經過旋轉了的數組
        int i = binarySearchForRevolve(nums, 7, 0, nums.length - 1);
        System.out.println(i);
    }

    /**
     * 二分搜索遞歸寫法
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int binarySearch(int[] nums, int target, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(nums[middle] == target) return middle;

        if(target < nums[middle]){
            return binarySearch(nums, target, low, middle - 1);
        }else{
            return binarySearch(nums, target, middle + 1, high);
        }
    }

    /**
     * 二分搜索非遞歸寫法
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int binarySearch2(int[] nums, int target, int low, int high){
        while (low <= high){
            int middle = low + (high - low)/2;

            if(nums[middle] == target) return middle;

            if(target < nums[middle]){
                high = middle - 1;
            }else{
                low = middle + 1;
            }
        }

        return -1;
    }

    /**
     * 二分搜索遞歸寫法——變形(尋找下邊界)
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int searchLowerBound(int[] nums, int target, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(nums[middle] == target && (middle == 0 || nums[middle - 1] < target)) return middle;

        if(target <= nums[middle]){
            return searchLowerBound(nums, target, low, middle - 1);
        }else{
            return searchLowerBound(nums, target, middle + 1, high);
        }
    }

    /**
     * 二分搜索遞歸寫法——變形(尋找上邊界)
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int searchUpperBound(int[] nums, int target, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(nums[middle] == target && (middle == nums.length - 1 || nums[middle + 1] > target)) return middle;

        if(target < nums[middle]){
            return searchUpperBound(nums, target, low, middle - 1);
        }else{
            return searchUpperBound(nums, target, middle + 1, high);
        }
    }

    /**
     * 二分搜索遞歸寫法——變形(尋找模糊邊界)
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int firstGreaterThan(int[] nums, int target, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(nums[middle] > target && (middle == 0 || nums[middle - 1] <= target)) return middle;

        if(target < nums[middle]){
            return firstGreaterThan(nums, target, low, middle - 1);
        }else{
            return firstGreaterThan(nums, target, middle + 1, high);
        }
    }

    /**
     * 二分搜索遞歸寫法——變形(經過旋轉了的數組)
     * @param nums
     * @param target
     * @param low
     * @param high
     * @return
     */
    public static int binarySearchForRevolve(int[] nums, int target, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(nums[middle] == target) return middle;

        if(nums[low] <= nums[middle]){      //判斷左半邊是否排好序
            if(nums[low] <= target && target < nums[middle]){   //判斷目標值是否在左半邊
                return binarySearchForRevolve(nums, target, low, middle - 1);
            }
            return binarySearchForRevolve(nums, target, middle + 1, high);
        }else{
            if(nums[middle] < target && target <= nums[high]){  //判斷目標值是否在右半邊
                return binarySearchForRevolve(nums, target, middle + 1, high);
            }
            return binarySearchForRevolve(nums, target, low, middle - 1);
        }
    }

    /**
     * 不定長邊界(先利用二分搜索思想找邊界,在使用普通二分搜索)
     * @param logs
     * @param high
     * @return
     */
    public static int getUpperBound(String[] logs, int high){
        if(logs[high] == null){
            return high;
        }
        return getUpperBound(logs, high*2);
    }

    /**
     * 利用二分搜索查找日志
     * @param logs
     * @param low
     * @param high
     * @return
     */
    public static int binarySearch(String[] logs, int low, int high){
        if(low > high) return  -1;

        int middle = low + (high - low)/2;

        if(logs[middle] == null && logs[middle - 1] != null) return middle;

        if(logs[middle] == null){
            return binarySearch(logs, low, middle - 1);
        }else{
            return binarySearch(logs ,middle + 1, high);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM