常见的查找算法(二):二分查找
二分搜索(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。
搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
再次注意:是在有序数组中进行的二分查找。
二分查找代码如下:
1 //迭代 2 public static int BinarySearch1(int[] a, int value, int n) { 3 int low, high, mid; 4 low = 0; 5 high = n - 1; 6 //一直循环 7 while (low <= high) { 8 mid = (low + high) >> 1; 9 count++; 10 if (a[mid] == value) 11 return mid; 12 count++; 13 if (a[mid] > value) 14 high = mid - 1;//查找范围变为0到mid-1 15 else 16 low = mid + 1;//查找范围变为mid+1到high 17 } 18 return -1; 19 } 20 21 //递归 22 public static int BinarySearch2(int[] a, int value, int low, int high) { 23 if(low > high) 24 return -1; 25 int mid = low + ((high - low) >> 1); 26 //若是中间那个值则直接返回 27 count++; 28 if (a[mid] == value) 29 return mid; 30 count++; 31 if (a[mid] > value) 32 return BinarySearch2(a, value, low, mid - 1);//往数组左边查找 33 else 34 return BinarySearch2(a, value, mid + 1, high);//往数组右边查找 35 }
二分搜索在情况下的复杂度是对数时间,进行O(log₂(n+1))次比较操作,平均时间复杂度为O(log₂n)。二分搜索使用常数空间,无论对任何大小的输入数据,算法使用的空间都是一样的。除非输入数据数量很少,否则二分搜索比线性搜索更快,但数组必须事先被排序。
测试代码:
1 public static void main(String[] args) { 2 int[] arr = {1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22}; 3 4 //二分查找的前提是在排好序的数组中查找 5 QuickSort.quickSorts(arr, 0, arr.length - 1); 6 System.out.println(Arrays.toString(arr)); 7 8 int result = BinarySearch1(arr, 22, arr.length); 9 //int result = BinarySearch2(arr, 22, 0, arr.length-1); 10 11 if (result != -1) 12 System.out.println("在数组中的位置:" + (result + 1)); 13 else 14 System.out.println("要查找的数不出存在"); 15 16 System.out.println("比较次数:"+count); 17 }