算法 - 二分查找(普通二分 和 递归二分)
1.1 二分查找的介绍
-
二分查找(Binary Search)算法,也叫折半查找算法,当我们要从一个序列中查找一个元素的时候,二分查找是一种非常快速的查找算法,**二分查找是针对有序数据集合的查找算法,如果是无序数据集合就遍历查找
-
二分查找之所以快速,是因为它在匹配不成功的时候,每次都能排除剩余元素中一半的元素。因此可能包含目标元素的有效范围就收缩得很快,而不像顺序查找那样,每次仅能排除一个元素
-
一个有序的数组中查找某个数字是否存在
1.2 普通二分查找
/**
* @author 云梦归遥
* @date 2022/5/14 16:56
* @description 二分查找的算法实现
*/
public class BinarySearch {
/**
* 二分查找实现查找序列中指定元素的索引
* @param array 目标数组
* @param num 目标元素
* @return 目标元素索引
*/
public int binarySearch(int[] array, int num){
// 如果数组为 null,则直接抛出异常
if (array == null) throw new RuntimeException();
int lower = 0; // 低位索引
int higher = array.length - 1; // 高位索引
int middle = 0; // 每次二分查找的中间索引
while (true){
middle = (lower + higher) / 2;
// 如果要查询的数字 等于 中间值,则直接返回中间值的索引
if (num == array[middle]) return middle;
if (lower >= higher) return -1;
// 如果要查询的数字 小于 中间值,则高位索引更新
if (num < array[middle]) higher = --middle;
// 如果要查询的数字 大于 中间值,则低位索引更新
else lower = ++middle;
}
}
}
1.3 二分查找的递归实现
/**
* @author 云梦归遥
* @date 2022/5/14 16:56
* @description 二分查找的算法实现
*/
public class BinarySearch {
/**
* 二分查找 + 递归 实现 查找序列中指定元素的索引
* @param array
* @param num
* @param lower
* @param higher
* @return
*/
public int binarySearchByRecursive(int[] array, int num, int lower, int higher){
if (lower > higher) return -1;
int middle = (lower + higher) / 2;
if (num == array[middle]){
return middle;
} else if (num > array[middle]){
return binarySearchByRecursive(array, num, middle + 1, higher);
} else {
return binarySearchByRecursive(array, num, lower, middle - 1);
}
}
}
1.4 进行测试
package com.lagou.binarySearchMethod.test;
import com.lagou.binarySearchMethod.BinarySearch;
/**
* @author 云梦归遥
* @date 2022/5/14 17:03
* @description
*/
public class BinarySearchTest {
public static void main(String[] args) {
int[] array = new int[]{1, 3, 5, 7, 9, 11, 13};
System.out.println("==================【二分查找】==================");
System.out.println("目标数组:" + array.length);
BinarySearch binarySearch = new BinarySearch();
int result1 = binarySearch.binarySearch(array, 11);
System.out.println("11 的索引为:" + result1);
int result2 = binarySearch.binarySearch(array, 5);
System.out.println("5 的索引为:" + result2);
int result3 = binarySearch.binarySearch(array, 20);
System.out.println("20 的索引为:" + result3);
System.out.println("==================【二分查找 + 递归】==================");
System.out.println("目标数组:" + array.length);
int result4 = binarySearch.binarySearch(array, 11);
System.out.println("11 的索引为:" + result4);
int result5 = binarySearch.binarySearch(array, 5);
System.out.println("5 的索引为:" + result5);
int result6 = binarySearch.binarySearch(array, 20);
System.out.println("20 的索引为:" + result6);
}
}
1.5 总结
-
使用二分查找: 1 有序、 2、时间复杂度 O(logn)
-
时间复杂度的计算:
第一次查找: T(1) = n/2
第二次查找: T(2) = n/2^2
第三次查找: T(3) = n/2^3
…
第M次查找: T(M) = n/2^M
数据规模大于等于1即 n/2^M >=1 ,说明不能再继续二分查找的操作,当数据规模达到最小值1时即n/2^M =1则是最坏的查找情况。T(M) = n/2^M = 1 得到M=O(N)=log2n,二分查找的时间复杂度为以2为底数n为指数的对数
-