刚学完二分查找法,虽然该方法很简单,可是仍是颇有不少坑值得记录一下。java
二分查找法的时间复杂度为对数阶,因此他相对于顺序查找法来讲效率较高。git
这里我决定分块阐述,不直接把代码端上来了。应为咱们知道,这里可能会有两种状况,一种是咱们只查询单个数的索引,它没有重复的数据;另外一种则是数组中有重复数据的出现。算法
这里咱们使用了基数排序法(也是对昨天所学的一个复习)对数组排了序,因此最后返回的是排好序的索引结果。数组
public static void main(String[] args) { int[] arr = { 1, 2, 5, 4, 3, 15, 22 }; BucketSort(arr); System.out.println(Arrays.toString(arr)); ArrayList<Integer> result = binarySearch02(arr, 0, 8, 3); System.out.println(result); }
此方法能够见我上一篇文章的详解,这里再也不赘述。函数
/** * 基数排序法 * * @param arr */ private static void BucketSort(int[] arr) { int[][] bucket = new int[10][arr.length]; int[] bucketCounts = new int[10]; int max = arr[0]; for (int i = 1; i < arr.length; ++i) { if (arr[i] > max) { max = arr[i]; } } int maxLength = (max + "").length(); for (int i = 0, n = 1; i < maxLength; ++i, n *= 10) { for (int j = 0; j < arr.length; ++j) { int digitofElement = arr[j] / n % 10; bucket[digitofElement][bucketCounts[digitofElement]] = arr[j]; bucketCounts[digitofElement]++; } int index = 0; for (int k = 0; k < bucket.length; ++k) { if (bucketCounts[k] != 0) { for (int l = 0; l < bucketCounts[k]; ++l) { arr[index] = bucket[k][l]; index++; } } bucketCounts[k] = 0; } } }
这里采用了递归而没有使用循环,一方面是对本身递归的一个锻炼,另外一个方面递归的效率优于循环。code
private static int binarySearch(int[] arr, int left, int right, int value) { if (left > right) { return -1; } int mid = (left + right) / 2; if (value > arr[mid]) { return binarySearch(arr, mid + 1, right, value); } else if (value < arr[mid]) { return binarySearch(arr, left, mid - 1, value); } else { return mid; } }
注意:这里也是我在敲代码的时候领悟的一点:使用递归时,若是函数有返回值,那么递归递归调用也必须 return!!!这有这样,在最底层return回来的数据才能被return给调用者。排序
这里的1)、2)跟前面相差不大,主要是对查找算法的改变。递归
private static ArrayList<Integer> binarySearch02(int[] arr, int left, int right, int value) { if (left > right) { return new ArrayList<Integer>(); } int mid = (left + right) / 2; if (value > arr[mid]) { return binarySearch02(arr, mid + 1, right, value); } else if (value < arr[mid]) { return binarySearch02(arr, left, mid - 1, value); } else { ArrayList<Integer> list = new ArrayList<>(); int tmp = mid - 1; while (true) { if (tmp < 0 || arr[tmp] != value) { break; } list.add(tmp); tmp--; } list.add(mid); tmp = mid + 1; while (true) { if (tmp > arr.length || arr[tmp] != value) { break; } list.add(tmp); tmp++; } return list; } }
改变之处:索引
ArrayList
集合,里面放索引