zcq

    1. package com.atguigu.search;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. //注意:使用二分查找的前提是 该数组是有序的.
    5. public class BinarySearch {
    6. public static void main(String[] args) {
    7. //int arr[] = { 1, 8, 10, 89,1000,1000, 1234 };
    8. int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12, 13,14,15,16,17,18,19,20 };
    9. //
    10. // int resIndex = binarySearch(arr, 0, arr.length - 1, 1000);
    11. // System.out.println("resIndex=" + resIndex);
    12. List<Integer> resIndexList = binarySearch2(arr, 0, arr.length - 1, 1);
    13. System.out.println("resIndexList=" + resIndexList);
    14. }
    15. // 二分查找算法
    16. /**
    17. *
    18. * @param arr
    19. * 数组
    20. * @param left
    21. * 左边的索引
    22. * @param right
    23. * 右边的索引
    24. * @param findVal
    25. * 要查找的值
    26. * @return 如果找到就返回下标,如果没有找到,就返回 -1
    27. */
    28. public static int binarySearch(int[] arr, int left, int right, int findVal) {
    29. // 当 left > right 时,说明递归整个数组,但是没有找到
    30. if (left > right) {
    31. return -1;
    32. }
    33. int mid = (left + right) / 2;
    34. int midVal = arr[mid];
    35. if (findVal > midVal) { // 向 右递归
    36. return binarySearch(arr, mid + 1, right, findVal);
    37. } else if (findVal < midVal) { // 向左递归
    38. return binarySearch(arr, left, mid - 1, findVal);
    39. } else {
    40. return mid;
    41. }
    42. }
    43. //完成一个课后思考题:
    44. /*
    45. * 课后思考题: {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,
    46. * 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000
    47. *
    48. * 思路分析
    49. * 1. 在找到mid 索引值,不要马上返回
    50. * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    51. * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    52. * 4. 将Arraylist返回
    53. */
    54. public static List<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
    55. System.out.println("hello~");
    56. // 当 left > right 时,说明递归整个数组,但是没有找到
    57. if (left > right) {
    58. return new ArrayList<Integer>();
    59. }
    60. int mid = (left + right) / 2;
    61. int midVal = arr[mid];
    62. if (findVal > midVal) { // 向 右递归
    63. return binarySearch2(arr, mid + 1, right, findVal);
    64. } else if (findVal < midVal) { // 向左递归
    65. return binarySearch2(arr, left, mid - 1, findVal);
    66. } else {
    67. // * 思路分析
    68. // * 1. 在找到mid 索引值,不要马上返回
    69. // * 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    70. // * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    71. // * 4. 将Arraylist返回
    72. List<Integer> resIndexlist = new ArrayList<Integer>();
    73. //向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    74. int temp = mid - 1;
    75. while(true) {
    76. if (temp < 0 || arr[temp] != findVal) {//退出
    77. break;
    78. }
    79. //否则,就temp 放入到 resIndexlist
    80. resIndexlist.add(temp);
    81. temp -= 1; //temp左移
    82. }
    83. resIndexlist.add(mid); //
    84. //向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList
    85. temp = mid + 1;
    86. while(true) {
    87. if (temp > arr.length - 1 || arr[temp] != findVal) {//退出
    88. break;
    89. }
    90. //否则,就temp 放入到 resIndexlist
    91. resIndexlist.add(temp);
    92. temp += 1; //temp右移
    93. }
    94. return resIndexlist;
    95. }
    96. }
    97. }