剛學完二分查找法,雖然該方法很簡單,可是仍是頗有不少坑值得記錄一下。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
集合,裏面放索引