我所知道的查找算法之二分查找法

做者前言

你們好,我是阿濠,今篇內容跟你們分享的是查找算法之二分查找法,很高興分享到segmentfault與你們一塊兒學習交流,初次見面請你們多多關照,一塊兒學習進步.

1、二分查找法的介紹

是一種在有序數組中查找某一特定元素的搜索算法。算法

1.搜索過程從數組的中間元素開始,若是中間元素正好是要查找的元素,則搜索結束segmentfault

2.若是某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,並且從新開始從中間元素進行比較。數組

3.若是在某一步驟數組爲空,則表明找不到。這種搜索算法每一次比較都使搜索範圍縮小一半學習

2、經過應用示例認識線性查找算法

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

步驟思路
1.肯定數組中間數的下標mid=(left+right)/2
2.將查詢的數findValue和中間數arr[mid]進行比較
3.若findVale>arr[mid],則說明查找的數findValue在右邊,進行遞歸向右查詢
4.若findVale<arr[mid],則說明查找的數findValue在左邊,進行遞歸向左查詢
5.若findVale = =arr[mid],則說明查找的數已找到並返回下標遞歸

結束遞歸思路
1.找到findValue結束遞歸
2.數組遞歸完仍未找到findValue也結束遞歸,當left>right結束遞歸退出索引

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

    //1、沒有找到的狀況
    if(left > right){
        return -1;
    }

    //2、找到的狀況
    //中間下標
    int mid = (left + right) / 2;
    int midVal =arr[mid];//中間下標對應的值

    if(findVal>midVal) {
        //若`findVale>arr[mid]`,則說明查找的數`findValue在右邊`,進行遞歸`向右查詢`
        return binarySearch(arr, mid + 1, right, findVal);
    }else if (findVal<midVal){
        //若`findVale<arr[mid]`,則說明查找的數`findValue在左邊`,進行遞歸`向左查詢`
        return binarySearch(arr,left,mid-1,findVal);
    }else{
        //若`findVale = =arr[mid]`,則說明`查找的數已找到並返回下標`
        return mid;
    }
}
public static void main(String[ ] args) {
    int arr[]={ 1, 8, 10, 89, 1000, 1234};
    int rearchIndex = binarySearch(arr,0,arr.length-1,8);
    if(rearchIndex == -1) {
        System. out. println("沒有找到");
    } else {
        System .out. println("找到,下標爲=" + rearchIndex);
    }
}
運行結果以下:
找到,下標爲 = 1

3、數組中出現重複數值

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

//二分查找算法
/**
 * 課後思考題: {1,8, 10,89,1000, 1000, 1234} 當一個有序數組中,
 * 有多個相同的數值時,如何將全部的數值都查找到,好比這裏的1000
 *
 * 思路分析
 * 1.在找到mid 索引值,不要立刻返回.
 * 2.向mid 索引值的左邊掃描,將全部知足1000,的元素的下標,加入到集合ArrayList
 * 3.向mid 索引值的右邊掃描,將全部知足1000, 的元素的下標,加入到集合ArrayList
 * 4.將Arraylist返 回
 */
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {

    //1、沒有找到的狀況
    if(left > right){
        return new ArrayList<Integer>();
    }

    //2、找到的狀況
    //中間下標
    int mid = (left + right) / 2;
    int midVal =arr[mid];//中間下標對應的值

    if(findVal>midVal) {
        //若`findVale>arr[mid]`,則說明查找的數`findValue在右邊`,進行遞歸`向右查詢`
        return binarySearch2(arr, mid + 1, right, findVal);
    }else if (findVal<midVal){
        //若`findVale<arr[mid]`,則說明查找的數`findValue在左邊`,進行遞歸`向左查詢`
        return binarySearch2(arr,left,mid-1,findVal);
    }else{
        /**思路分析
         * 1.在找到mid 索引值,不要立刻返回.
         * 2.向mid 索引值的左邊掃描,將全部知足1000,的元素的下標,加入到集合ArrayList
         * 3.向mid 索引值的右邊掃描,將全部知足1000, 的元素的下標,加入到集合ArrayList
         * 4.將Arraylist返回
         * */
        ArrayList<Integer> rearchIndexlist=new ArrayList<Integer>();
        //向mid 索引值的左邊掃描,將全部知足1000,的元素的下標,加入到集合ArrayList
        int temp= mid - 1;
        while(true){
            //證實向mid 索引值的左邊掃描 沒有找到相同的findValue值
            if(temp < 0 || arr[temp] != findVal ){
                break;
            }
            //證實有相同的findValue值,放入rearchIndexlist裏
            rearchIndexlist.add(temp);
            temp -= 1;//向左移
        }
        //將找到的mid 索引值 放入rearchIndexlist 中
        rearchIndexlist.add(mid);

        //向mid 索引值的右邊掃描,將全部知足1000, 的元素的下標,加入到集合ArrayList
        temp= mid + 1;
        while(true){
            //證實向mid 索引值的右邊掃描 沒有找到相同的findValue值
            if(temp > arr.length -1 || arr[temp]!= findVal ){
                break;
            }
            //證實有相同的findValue值,放入rearchIndexlist裏
            rearchIndexlist.add(temp);
            temp += 1;//向右移
        }
        return rearchIndexlist;
    }
}
public static void main(String[ ] args) {

    int arr[]={ 1, 10, 89, 1000, 1000, 1234};

    List integerList= binarySearch2(arr,0,arr.length-1,1000);
    System.out.println("找到的全部值:"+ integerList);
        
}

運行結果以下:
找到的全部值:[3,4]
相關文章
相關標籤/搜索