二分查找算法
算法思想
二分查找又称折半查找,其算法核心思想是对一组有序的数据集不断的进行对半分隔,并检查每个分区的中间元素是否为被查找的目标元素。
适用前提
在上面的定义中,我们知道二分查找算法只能适用于有序数据集,如果数据集为无序的,那么算法将失效。
时间复杂度
二分查找算法的时间复杂度与有序数据集的元素个数有关,假设有序数据集有 n 个元素,其时间复杂度为:
O ( log 2 n ) O(\log_2 n) O(log2n)
实现过程
此实现过程主要是通过游标变量 left 和 right 控制一个循环来查找元素(其中left和right是待查找数据集的左右两个边界)。首先,将 left 和 right 分别设置为 0 和 size -1。在循环的每次迭代中,将变量 mid 设置为 left 和 right 之间区域的中间值。如果处于mid的元素值小于目标值,则将 left 代表的索引移动到 mid 后的一个元素的位置上,即下一组要搜索的区域是当前数据集的上半区。如果 mid 位置的元素大于目标元素,则将 right 代表的索引移动到 mid 前一个元素的位置上,即下一组要搜索的区域是当前数据集的下半区。随着不断的搜索,left 不断向右移,right 不断向左移,直到 mid 处找到目标元素或者 left 和 ***right***重合时算法结束。这个过程可以用如下图来表示:
代码实现
JavaScript实现
function binary_search(arr,item) {
var left = 0; //数组的左边界
var right = arr.length - 1; //数组的右边界
while (left <= right) {
var mid = (left + right) / 2;
var guess = arr[mid];
if (guess == item) {
return mid;
} else if (guess > item) {
right = mid - 1; // 如果中间值大于目标值,则将右边索引移动到中间值的前一个元素的位置上
} else {
left = mid + 1; // 如果中间值小于目标值,则将左边索引移动到中间值的后一个元素的位置上
}
}
return -1;
}
Python实现
def binary_search(list, item):
left = 0 # 表示左边界索引
right = len(list) - 1 # 表示有边界索引
while left <= right:
mid = int((left + right) / 2) # 表示中间值的索引
guess = list[mid]
if guess == item:
return mid; # 如果中间值等于目标值,返回目标值的索引
if guess > item:
right = mid - 1 # 如果中间值大于目标值,则将右边索引移动到中间值的前一个元素的位置上
else:
left = mid + 1 # 如果中间值小于目标值,则将左边索引移动到中间值的后一个元素的位置上
return None
Java实现
public static int binarySearch(int[] array,int item) {
int left = 0;
int right = array.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
int guess = array[mid];
if (guess == item) {
return mid;
} else if (guess > item) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}