PCB的發展歷史及展望
阿新 • • 發佈:2020-10-17
二分查詢前提
進行二分查詢的陣列是有序陣列
二分查詢演算法思路
- 首先確定該陣列的中間下標 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; } }