查找算法之二分查找
思路:
二分查找是基于有序数组才能使用,这里举例的是从小到大的有序数组。通过中轴值与目标值进行比较,来判断目标值是在中轴的左边还是右边,以此来缩小查找范围。利用递归进行不断查找,没有找到那么退出。如果找到了,就向左向右循环看看紧挨着的值是否也等于目标值,如果等于,那么也将它们的下标返回出去。
代码:
1 /** 2 * 二分查找 3 * @param arr 从小到大的有序数组 4 * @param left 数组的左索引 5 * @param right 数组的右索引 6 * @param value 寻找的目标值 7 * @return 8 */ 9 public static List<Integer> binarySearch(int[] arr, int left, int right, int value) { 10 if (arr == null || arr.length == 0) { 11 return Collections.emptyList(); 12 } 13 if (left > right) { 14 //在数组中没有找到目标值 15 return Collections.emptyList(); 16 } 17 //中轴 18 int pivot = (left + right) / 2; 19 //值等于value的下标的集合 20 ArrayList<Integer> result = new ArrayList<>(arr.length); 21 //将中轴指向的值与value比较 22 if (value < arr[pivot]) { 23 //如果value小,那从左边找 24 return binarySearch(arr, left, pivot - 1, value); 25 } else if (value > arr[pivot]) { 26 //如果value大,那从右边找 27 return binarySearch(arr, pivot + 1, right, value); 28 } else { 29 int temp = pivot; 30 //如果相等,那看看左右紧挨着的值是否也相等 31 while (temp >= 0 && arr[temp] == value) { 32 //向左查找 33 result.add(temp); 34 temp--; 35 } 36 temp = pivot + 1; 37 while (temp <= arr.length - 1 && arr[temp] == value) { 38 //向右查找 39 result.add(temp); 40 temp++; 41 } 42 } 43 return result; 44 }