二分查找算法主要是解决在“一堆数中找出指定的数”这类问题。
而想要应用二分查找法,这“一堆数”必须有一下特征:
- 存储在数组中
- 有序排列
二分查找法的基本实现
二分查找法在算法家族大类中属于“分治法”,分治法基本都可以用递归来实现的,二分查找法的递归实现如下:
/*
* 递归实现
*/
private static boolean divideRecur(int[] aa, int left, int right, int tt) {
if(left > right) {
return false;
}
int mid = left + ((right - left)>>1);//防止溢出
if(tt == aa[mid]) {
return true;
}else if(tt < aa[mid]) {
return divideRecur(aa, left, mid -1, tt);
}else {
return divideRecur(aa, mid +1, right, tt);
}
}
迭代实现如下:
/*
* 迭代实现
*/
private static boolean divideTest(int[] aa, int tt) {
int size = aa.length;
int left =0;
int right = size -1;
int midIndex = 0;
int midValue = 0;
while(left <= right) {
midIndex = left +((right - left)>> 1);
midValue = aa[midIndex];
if(tt==midValue) {
return true;
}else if(tt<midValue) {
right = midIndex -1;
}else {
left = midIndex + 1 ;
}
}
return false;
}
二分查找法的O(log n)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。就在它的限定之上:
必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组。
数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组变成低效的事情。