java實現二分查找

二分查找(binary search),也稱折半搜索,是一種在 有序數組 中 查找某一特定元素 的搜索算法。搜索過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結束;如果某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數組爲空,則代表找不到。這種搜索算法每一次比較都使搜索範圍縮小一半。

  • 時間複雜度:折半搜索每次把搜索區域減少一半,時間複雜度爲O(log n)。(n代表集合中元素的個數)
  • 空間複雜度: O(1)。雖以遞歸形式定義,但是尾遞歸,可改寫爲循環。

動圖演示

binary-search

代碼描述

binarySearch遞歸查詢某個數據的下標,binarySearch2查詢的數據在數組中有重複值也能一併將該數據所有下標返回。
import java.util.ArrayList;
import java.util.List;

public class BinarySearch {

    public static void main(String[] args) {
        int[] arr = {1, 22 , 34 , 89 , 200 ,1000 ,1234, 1456};
        int resIndex = binarySearch(arr, 0,arr.length -1 , 1000);
        System.out.println(resIndex);

        //搜索的數據在數組中包含重複值時,一併將重複數據的所有下標獲取
//        int[] arr = {1, 22 , 89 , 200 , 1000 , 1000 ,1000 ,1234};
//        List<Integer> resIndexList = binarySearch2(arr, 0,arr.length -1 , 1000);
//        System.out.println(resIndexList);
    }

    public static int binarySearch(int[] arr, int left, int right, int findVal){
        //當left > right 時,說明遞歸整個數組,但是沒有找到
        if(left > right){
            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;
        }

    }

    //重複數據下標一併返回
    public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal){
        //當left > right 時,說明遞歸整個數組,但是沒有找到
        if(left > right){
            return new ArrayList<>();
        }

        int mid = (left + right) / 2;
        int midVal = arr[mid];

        if(findVal > midVal){
            return binarySearch2(arr, mid + 1 , right , findVal);
        }else if(findVal < midVal){
            return binarySearch2(arr, left , mid - 1 , findVal);
        }else{
            List<Integer> resIndexList = new ArrayList<Integer>();

            int temp = mid - 1;
            while(true){
                if(temp < 0 || arr[temp] != findVal){
                    break;
                }
                resIndexList.add(temp);
                temp--;
            }
            resIndexList.add(mid);

            temp = mid + 1;
            while(true){
                if(temp > arr.length + 1 || arr[temp] != findVal){
                    break;
                }
                resIndexList.add(temp);
                temp++;
            }
            return resIndexList;
        }

    }
}

 運行結果:

binarySearch2 我沒有驗證了,大家放開代碼中的註釋,自行驗證吧。

文章開始描述和動態圖解參考這裏的:https://www.cnblogs.com/morethink/p/8379475.html

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