1. 程式人生 > 實用技巧 >PCB的發展歷史及展望

PCB的發展歷史及展望

二分查詢前提

進行二分查詢的陣列是有序陣列

二分查詢演算法思路

  • 首先確定該陣列的中間下標 mid = (left+right)/2
  • 然後讓需要查詢的數和arr[mid]進行比較
    • findVal > arr[mid] 說明你要查詢的數在mid的右邊,因此需要遞歸向右進行查詢
    • findVal < arr[mid] 說明你要查詢的數在mid的左邊,因此需要遞歸向左進行查詢
    • findVal = arr[mid] 說明找到,返回

注意:
使用遞迴要特別注意結束條件,不然就會成為死遞迴

  • 找到就結束遞迴
  • 遍歷完整個陣列,仍然沒有找到findVal,也需要結束遞迴 當left>right時就結束了

程式碼實現

實現返回找到的第一個值的下標

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

    /**
     * @param arr     陣列
     * @param left    左邊的下標
     * @param right   右邊的下標
     * @param findVal 查詢的值
     * @return 返回查詢到的第一個下標
     */
    private static int binarySearch(int[] arr, int left, int right, int findVal) {
        if (findVal < arr[left] || findVal > arr[right] || left > right) { //沒有找到
            return -1;
        }
        int mid = (left + right) / 2;
        if (findVal < arr[mid]) { //findVal小於中間值 ,則說明在左邊,需要左遞迴
            return binarySearch(arr, left, mid - 1, findVal);
        } else if (findVal > arr[mid]) { // findVal大於中間值,需要向右遞迴
            return binarySearch(arr, mid + 1, right, findVal);
        } else { //相等
            return mid;
        }
    }

返回多個下標

如果陣列中待查詢的元素有多個,這時就需要返回多個下標.核心思想就是藉助於上面查詢到的一個下標,向左右兩邊依次查詢,是否還有與findVal相等的值

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

    /**
     * @param arr     陣列
     * @param left    左邊的下標
     * @param right   右邊的下標
     * @param findVal 待查詢的值
     * @return 返回查詢元素下標的集合
     */
    private static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
        //遞迴結束條件
        if (findVal < arr[left] || findVal > arr[right] || left > right) {
            return new ArrayList<Integer>();
        }
        List<Integer> indexList = new ArrayList<>();
        int mid = (left + right) / 2;
        if (findVal < arr[mid]) {
            return binarySearch2(arr, left, mid - 1, findVal);
        } else if (findVal > arr[mid]) {
            return binarySearch2(arr, mid + 1, right, findVal);
        } else {
            //找到一個下標mid之後,需要像mid的左右兩邊進行遍歷,把值相等的下標,新增到集合中返回
            int temp = mid - 1;
            //向左邊查詢
            while (true) {
                if (temp < 0 || arr[temp] != findVal) {
                    break;
                }
                indexList.add(temp);
                temp -= 1;
            }

            //新增mid
            indexList.add(mid);

            temp = mid + 1;
            //向右邊查詢
            while (true) {
                if (temp > arr.length - 1 || arr[temp] != findVal) {
                    break;
                }
                indexList.add(temp);
                temp += 1;
            }

            return indexList;
        }
    }