网上有看到说大多数程序员都不能写出二分查找的算法,所以呢,我不能成为那大多数程序员中的一个,果然瞎琢磨了半天,还是写出来了,mark下吧。
二分查找的数组得是从小到大升序排序的,将数组的n个元素分成两部分,search与a[n/2]进行比较,search < a[n / 2]那就从数组的左半部分搜索,search > a[n / 2]就从数组的右半部分搜索。其时间复杂度无非是while循环执行的次数,搜索数组长度变化的过程是
n, n/2, n/4, ...n/2^k, k就是执行的次数,
由于n/2^k取整>=1 (长度不能小于1吧,呵呵)
令n/2^k=1
可得k=log2n, 是以2为底, n的对数
这样时间复杂度就可以表示成O(logn)
show you the code:
public class BinarySearch {
public static void main(String[] args) {
int[] a = {4, 5, 12, 13, 15, 17, 18, 23, 25, 27, 34, 34, 35, 38, 49, 49, 51, 53, 54, 56, 62, 64, 65, 76, 78, 97, 98, 99};
int search = 5;
System.out.println(binarySearch(a, search));
}
public static int binarySearch(int[] a, int search) {
int left = 0;
int right = a.length - 1;
int mid = a.length / 2;
if (search == a[mid]) {
return mid;
}
// 这个地是 <=,当数据是偶数的时候,left 最后会等于 right
while (left <= right) {
// mid = (right + left) / 2;
// 上面这种写法可能会导致溢出,比如用 4bit 表示一个数,当 left = 6, right = 7
// left + right = 13 就溢出了
// (left + right + left - left) / 2 = left + (right - left) / 2
mid = left + (right - left) / 2;
if (search < a[mid]) {
right = mid - 1;
} else if (search > a[mid]) {
left = mid + 1;
} else if (search == a[mid]) {
return mid;
}
}
return -1;
}
}