线性查找和二分查找
线性查找
从第一个遍历判断到最后一个,查找到全部符合条件的值。(遍历数组找到就返回下标值(如果有多个可先存储))
1. public class seqsearch { 2. public static void main(String[] args) { 3. int[] arr = {45, 23, 1, 12, 6, 78, 1, 156, 1, 1};// 没有顺序的数组 4. List<Integer> search = seqSearch(arr, 1); 5. if (search.size() == 0) { 6. System.out.println("未找到。。。。。"); 7. } else { 8. System.out.println(search.toString()); 9. } 10. } 11. 12. private static List<Integer> seqSearch(int[] arr, int value) { 13. ArrayList<Integer> list = new ArrayList<>(); 14. for (int i = 0; i < arr.length; i++) { 15. if (value == arr[i]) { 16. list.add(i); 17. } 18. } 19. return list; 20. 21. } 22. }
二分查找
二分查找算法的思路
1. 首先确定该数组的中间的下标:mid = (left + right) / 2
2. 然后让需要查找的数 findVal 和 arr[mid] 比较
2.1 findVal > arr[mid] , 说明你要查找的数在mid 的右边, 因此需要递归的向右查找
2.2 findVal < arr[mid], 说明你要查找的数在mid 的左边, 因此需要递归的向左查找
2.3 findVal == arr[mid] 说明找到,就返回
什么时候结束递归?
1) 找到就结束递归
2) 递归完整个数组,仍然没有找到findVal ,也需要结束递归 当 left > right 就需要退出
思考题
{1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000.
1. public class binarysearch { 2. public static void main(String[] args) { 3. //注意:使用二分查找的前提是 该数组是有序的. 4. int[] arr = {1, 23, 44, 56, 79, 79, 79, 79, 79, 79, 102, 336, 500}; 5. int search = binarySearch(arr, 0, arr.length - 1, 79); 6. List<Integer> searchAll = binarySearchAll(arr, 0, arr.length - 1, 79); 7. System.out.println(search); 8. System.out.println(searchAll); 9. } 10. 11. /** 12. * @param arr 数组 13. * @param left 左边的索引 14. * @param right 右边的索引 15. * @param findVal 要查找的值 16. * @return 如果找到就返回下标,如果没有找到,就返回 -1 17. */ 18. private static int binarySearch(int[] arr, int left, int right, int findVal) { 19. if (left > right) { // 当 left > right 时,说明递归整个数组,但是没有找到 20. return -1; 21. } else { 22. int mid = (left + right) / 2; 23. if (findVal > arr[mid]) { // 向 右递归 24. return binarySearch(arr, mid + 1, right, findVal); 25. } else if (findVal < arr[mid]) {// 向左递归 26. return binarySearch(arr, left, mid - 1, findVal); 27. } else { 28. return mid; 29. } 30. } 31. } 32. 33. /** 34. * 思考题: {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中, 35. * * 有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000 36. * * 37. * * 思路分析 38. * * *1. 在找到 mid 索引值,不要马上返回 39. * * *2. 向 mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合 ArrayList 40. * * *3. 向 mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合 ArrayList 41. * * *4. 将 Arraylist 返回 42. */ 43. private static List<Integer> binarySearchAll(int[] arr, int left, int right, int findVal) { 44. 45. if (left > right) { 46. return null; 47. } else { 48. int mid = (left + right) / 2; 49. if (findVal > arr[mid]) { 50. return binarySearchAll(arr, mid + 1, right, findVal); 51. } else if (findVal < arr[mid]) { 52. return binarySearchAll(arr, left, mid - 1, findVal); 53. } else { 54. ArrayList<Integer> list = new ArrayList<>(); 55. list.add(mid); 56. //向 mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合 ArrayList 57. int temp = mid - 1; 58. while (true) { 59. if (temp < 0 || arr[temp] != findVal) { 60. break; 61. } else { 62. list.add(temp); 63. temp--; //temp 左移 64. } 65. } 66. 67. //向 mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合 ArrayList 68. temp = mid + 1; 69. while (true) { 70. if (temp > arr.length - 1 || arr[temp] != findVal) { 71. break; 72. } else { 73. list.add(temp); 74. temp++;//temp 右移 75. } 76. } 77. return list; 78. } 79. } 80. } 81. }