二分查找
二分查找也称折半查找(Binary Search),它的查找效率很好。二分查找有一个要求是必须采用顺序存储结构,而且表种的元素是有序的。只有满足这个条件我们才能使用二分查找。
查找条件:
查找区域的左边界,小于等于查找区域的右边界
查找过程:
1. 循环条件 == 查找条件
2.计算序列中间下标位置
3.如果待查找值value == 中间位置的元素的值 返回当前中间位置下标
4.如果待查找值value > 序列中间位置元素的值 左边界等于中间位置+1
5.如果带查找值value < 序列中间位置元素的值 右边界等于中间位置-1
6.如果循环结束 返回 -1 (也就是没查找到,返回-1)
源代码:
/**
* 二分查找值元素
* 参数:数组 开始点 结束点 值
* 返回值:
* 找到了返回该点下标
* 找不到返回-1
* @param array
* @param value
* @param begin
* @param end
* @return
*/
public static int search(int[] array, int value, int begin, int end) {
while (begin <= end) { //查找区域的左边界,小于等于查找区域的右边界
int mid = (begin + end) / 2; //.计算序列中间下标位置
if (value == array[mid]) { //如果待查找值value == 中间位置的元素的值 返回当前中间位置下标
return mid;
} else if (value > array[mid]) { //如果待查找值value > 序列中间位置元素的值 左边界等于中间位置+1
begin = mid + 1;
} else { //如果带查找值calue < 序列中间位置元素的值 右边界等于中间位置-1
end = mid - 1;
}
}
return -1;
}
变种二分查找:
何为变种的二分查找,变种的二分查找就是在二分查找的模式下,查找各种你想要的和value直接的或间接的相关的元素。
下面是变种二分查找的架子。
while (begin <= end) {
int mid = (begin + end) / 2;
if (value (?) array[mid]) {
//操作
} else {
//操作
}
}
循环条件,计算中间值,都是一样的。这里我们着重看选择语句中的判断条件和执行的操作。
例如:数组元素中含有多个相同的元素,我们想查找和value相同的元素中第一个出现的。那么我们要怎么设计这个变种的二分查找算法呢?
查找条件:
查找区域的左边界,小于等于查找区域的右边界
查找过程:
1. 循环条件 == 查找条件
2.计算序列中间下标位置
4.如果待查找值value > 序列中间位置元素的值 右边界等于中间位置-1
5.如果带查找值value < 序列中间位置元素的值 左边界等于中间位置+1
6.如果循环结束 判断 左边界小于数组长度 并且左边界所在位置的值等于value 返回左边界下标
7.否则返回 -1 (也就是没查找到,返回-1)
/**
* 查找等于value 的元素中第一个出现的元素
*/
static int firstEqualEvent(int[] array, int value) {
int begin = 0;
int end = array.length - 1;
while (begin<= end) {
int mid = (begin + end) / 2;
if (array[mid] >= value) {
end = mid -1;
}
else {
begin = mid + 1;
}
}
if (begin< array.length && array[begin] == value) {
return begin;
}
return -1;
}
示例:相反要查找等于value 的元素中最后一个出现的元素、
/**
* 查找等于value 的元素中最后一个出现的元素
*/
static int firstEqualEvent(int[] array, int value) {
int begin = 0;
int end = array.length - 1;
while (begin<= end) {
int mid = (begin + end) / 2;
if (array[mid] <= value) {
begin = mid + 1;
}
else {
end = mid - 1 ;
}
}
if (end >=0 && array[end] == value) {
return end;
}
return -1;
}
总结:
变种的二分查找有很多种,我们可以自行去实现自己想要的查询方式,一般都不难理解。只要了解了什么是二分查找,自己脑海中能模拟出二分查找的规律,那么我相信对于变种的二分查找,你也能找到合理的实现方式。