算法與數據結構


 

二分法

二分法的前提是 在有序數組中,因此若是一個數組是無序的,咱們要先把無序數組變爲有序數組。算法

二分查找的思路分析:(假設該數組爲自左向右從小到大)數組

1.首先肯定該數組的中間的下標spa

 mid = (left + right) / 2 code

2.而後讓須要查找的數 findVal 和  arr[mid] 比較blog

有三種狀況:遞歸

        2.1 findVal > arr[mid],說明你要查找的數在mid的右邊,所以須要遞歸的向右查找
        2.2 findVal < arr[mid],說明你要查找的數在mid的左邊,所以須要遞歸的想作查找
        2.3 findVal = arr[mid],說明找到,就返回

// 何時咱們須要結束遞歸呢?索引

有兩種狀況:ip

1.找到數就結束遞歸io

2.遞歸完整個數組,仍然沒有找到 findVal ,也須要結束遞歸,即 left > right 就須要退出。class

代碼實現(基本寫法):

題目:請對一個有序數組進行二分查找{1, 8, 10, 89, 1000, 1234},輸入一個數看看該數組是否存在該數,而且求出下標,不然就提示,沒有這個數。

/**
 * @program: Julih
 * @description:
 * @author: wangxp
 * @create: 2019-11-18 21:40
 */
// 注意: 使用二分查找的前提是,數組是有序的.
public class BinarySearch {

    public static void main(String[] args) {
        int arr[] = {1, 8, 10, 89, 1000, 1234};
        int resIndex = binarySearch(arr, 0, arr.length - 1, 1111);
        System.out.println("resIndex is " + resIndex);
    }

    /**
     * 二分查找算法
     * @param arr   數組
     * @param left  左邊的索引
     * @param right 右邊的索引
     * @param findVal   要查找的值
     * @return  若是找到就返回下標,否咋返回-1
     */
    public static int binarySearch(int[] arr, int left, int right, int findVal){

        if (left > right){  // 若是沒有找到,就直接返回 -1
            return -1;
        }
        int mid = (left + right) / 2;  
        int midVal = arr[mid];    
        if (findVal > midVal){    // 向右遞歸
            return binarySearch(arr, mid+1, right,findVal);
        } else if (findVal < midVal){ // 向左遞歸
            return binarySearch(arr,left,mid -1, findVal);
        } else{ // 正好相等,找到了
            return mid;
        }
    }
}

 

二分查找(升級版):

題目:{1, 8, 10, 89, 1000, 1000,1000,1234},當一個有序數組中,有多個相同數值時,如何將全部的數值都查找到,好比這裏的1000?

/**
 * @program: Julih
 * @description:
 * @author: wangxp
 * @create: 2019-11-18 21:40
 */
// 注意: 使用二分查找的前提是,數組是有序的.
public class BinarySearch2 {

    public static void main(String[] args) {
        int arr[] = {1, 8, 10, 89, 1000, 1000, 1000, 1234};
        List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 1000);
        System.out.println("resIndexList is " + resIndexList.toString());
    }

    /**
     * 二分查找算法
     * @param arr   數組
     * @param left  左邊的索引
     * @param right 右邊的索引
     * @param findVal   要查找的值
     * @return  若是找到就返回下標,否咋返回-1
     */
    public static List<Integer> binarySearch(int[] arr, int left, int right, int findVal){

        if (left > right){  // 若是沒有找到,就直接返回 -1
            return new ArrayList<Integer>();
        }
        int mid = (left + right) / 2;       // 中間的下標
        int midVal = arr[mid];              // 中間的值
        if (findVal > midVal){           // 向右遞歸
            return binarySearch(arr, mid+1, right,findVal);
        } else if (findVal < midVal){ // 向左遞歸
            return binarySearch(arr,left,mid -1, findVal);
        } else{
            // 當已經找到的時候,先不退出,
            List<Integer> resIndexList = new ArrayList<Integer>();
            // 向mid 索引值得左邊掃描,將與findVal相等的值得下標,加入到ArrayList中.
            int temp = mid - 1;
            while (true){
                if (temp < 0 || arr[temp] != findVal){  // 退出
                    break;
                }
                // 不然,將 temp 放入到 resIndexList中
                resIndexList.add(temp);
                temp -= 1;  // 左移
            }
            resIndexList.add(mid);
            // 向mid 索引值得左邊掃描,將與findVal相等的值得下標,加入到ArrayList中.
            temp = mid + 1;
            while (true){
                if (temp > arr.length -1 || arr[temp] != findVal){
                    break;
                }
                // 不然,將 temp 放入到 resIndexList中
                resIndexList.add(temp);
                temp += 1;  // 右移
            }
            return resIndexList;
        }
    }
}
相關文章
相關標籤/搜索