1.前提

数组有序

2.思路

image.png

3.含有相同值的数组,只查询到一个的代码

例如:数组{ 1, 8, 10, 89,999,1000,1001,1234 },查询1000的位置

  1. public class BinarySearch {
  2. public static void main(String[] args) {
  3. int arr[] = { 1, 8, 10, 89,999,1000,1001,1234 };
  4. int resIndex = binarySearch(arr, 0, arr.length - 1, 1000);
  5. System.out.println(resIndex);
  6. }
  7. public static int binarySearch(int[] arr, int left, int right, int findVal){
  8. // 当 left > right 时,说明递归整个数组,但是没有找到
  9. if (left>right){
  10. return -1;
  11. }
  12. int mid = (left + right) / 2;
  13. int midVal = arr[mid];
  14. if (findVal > midVal){// 向 右递归
  15. return binarySearch(arr,mid+1,right,findVal);
  16. }else if (findVal < midVal) { // 向左递归
  17. return binarySearch(arr, left, mid - 1, findVal);
  18. } else {
  19. return mid;
  20. }
  21. }

运行结果

  1. 5//元素1000对应的数组下标为5

4.增强版(查询所有满足条件的元素下标)

如:查询数组 { 1, 8, 10, 89,1000,1000,1000,1234 }中 1000的元素下标

  1. public class BinarySearch {
  2. public static void main(String[] args) {
  3. int arr[] = { 1, 8, 10, 89,1000,1000,1000,1234 };
  4. int resIndex = binarySearch(arr, 0, arr.length - 1, 1000);
  5. List<Integer> resIndexList = binarySearch2(arr, 0, arr.length - 1, 1000);
  6. System.out.println("resIndexList=" + resIndexList);
  7. }
  8. public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
  9. // 当 left > right 时,说明递归整个数组,但是没有找到
  10. if (left > right) {
  11. return new ArrayList<Integer>();
  12. }
  13. int mid = (left + right) / 2;
  14. int midVal = arr[mid];
  15. if (findVal > midVal) { // 向 右递归
  16. return binarySearch2(arr, mid + 1, right, findVal);
  17. } else if (findVal < midVal) { // 向左递归
  18. return binarySearch2(arr, left, mid - 1, findVal);
  19. } else {
  20. // * 思路分析
  21. // * 1. 在找到mid 索引值,不要马上返回
  22. // * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
  23. // * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
  24. // * 4. 将Arraylist返回
  25. List<Integer> resindexlist = new ArrayList<Integer>();
  26. //向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
  27. int temp = mid - 1;
  28. while (true) {
  29. if (temp < 0 || arr[temp] != findVal) {//退出
  30. break;
  31. }
  32. //否则,就temp 放入到 resIndexlist
  33. resindexlist.add(temp);
  34. temp -= 1;//temp左移
  35. }
  36. resindexlist.add(mid);//将第一次找到的值加入列表
  37. temp = mid + 1;
  38. while (true) {
  39. if (temp > arr.length - 1 || arr[temp] != findVal) {//退出
  40. break;
  41. }
  42. //否则,就temp 放入到 resIndexlist
  43. resindexlist.add(temp);
  44. temp += 1;//temp左移
  45. }
  46. return resindexlist;
  47. }
  48. }
  49. }

运行结果

  1. resIndexList=[4, 5, 6]