1.时间复杂度:logn
每次查找后,数据规模缩减为原来的一半
2.代码实现
@Test
public void test() {
System.out.println("========" + bsearch(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9));
bsearch2(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9);
}
//非递归实现
public int bsearch(int[] array, int target) {
int low = 0;
int heigh = array.length - 1;
while (low <= heigh) {
int mid = (low + heigh) / 2;
if (array[mid] == target) return mid;
else if (array[mid] > target) {
heigh = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
//递归实现
public void bsearch2(int[] array, int target) {
System.out.println("-------" + realSearch(array, array.length - 1, 0, target));
}
public int realSearch(int[] array, int heigh, int low, int target) {
if (low > heigh) return -1;
int mid = low + ((heigh - low) >> 1);
if (array[mid] == target) return mid;
else if (array[mid] > target) {
return realSearch(array, mid - 1, low, target);
} else {
return realSearch(array, heigh, mid + 1, target);
}
}
3.适用范围
(1)查找依赖顺序表结构,即数组
(2)需要数组是有序状态
(3)数据量不能太大或者太小:因为数组需要连续空间,太大的数据量一次性载入内存有风险;太小的数据量没有时间上的优势
4.拓展-变体问题
@Test
public void test() {
// System.out.println("========" + bsearch(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9));
// bsearch2(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 9);
System.out.println("first target = " + firstTarget(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
System.out.println("last target = " + lastTarget(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
System.out.println("firstTargetBig target = " + firstTargetBig(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 6));
System.out.println("lastTargetSmall target = " + lastTargetSmall(new int[]{1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, 9));
}
//查找第一个值等于给定值的元素
public int firstTarget(int[] array, int target) {
int low = 0;
int heigh = array.length - 1;
while (low <= heigh) {
int mid = low + ((heigh - low) >> 1);
if (array[mid] > target) {
heigh = mid - 1;
} else if (array[mid] < target) {
low = mid + 1;
} else {
if (mid == 0 || array[mid - 1] != target)
return mid;
else
heigh = mid - 1;
}
}
return -1;
}
//查找最后一个值等于给定元素的值
public int lastTarget(int[] array, int target) {
int low = 0;
int heigh = array.length - 1;
while (low <= heigh) {
int mid = low + ((heigh - low) >> 1);
if (array[mid] > target) {
heigh = mid - 1;
} else if (array[mid] < target) {
low = mid + 1;
} else {
if (mid == array.length - 1 || array[mid + 1] != target) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}
//查找第一个大于等于给定值的元素
public int firstTargetBig(int[] array, int target) {
int low = 0;
int heigh = array.length - 1;
while (low <= heigh) {
int mid = low + ((heigh - low) >> 1);
if (array[mid] >= target) {
if (mid == 0 || array[mid - 1] < target) {
return mid;
} else {
heigh = mid - 1;
}
} else {
low = mid + 1;
}
}
return -1;
}
//查找最后一个小于等于给定值的元素
public int lastTargetSmall(int[] array, int target) {
int low = 0;
int heigh = array.length - 1;
while (low <= heigh) {
int mid = low + ((heigh - low) >> 1);
if (array[mid] > target) {
heigh = mid - 1;
} else {
if ((mid == array.length - 1) || array[mid + 1] > target) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}