一、基本概念
二分查找法(Binary Search)算法,也叫折半查找算法。二分查找要求数组数据必须采用顺序存储结构有序排列。查找思想有点类似于分治思想。每次都通过跟区间的中间元素对比,将带查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为0。二分查找是一种非常非常高效的查询算法,时间复杂度为O(logn)。
二、算法实现
之前有写过利用数组进行数据查找的文章,其采用的是二分查找,不过原先的实现代码并不通用,因为源代码只适用于整型数组,倘若要求在浮点数组或者字符串数组中查找,那只能重新编码了。
因此,对于这种基本逻辑结构雷同、仅有数据类型不同的算法,完全可以采取泛型的手段处理。
接下来就利用泛型实现通用的二分查找算法。
注意: 凡是实现了Comparable接口的数据类型(即包装类型,不是基本数据类型),它的数组都能运用泛型方法进行二分查找。
泛型方法的定义:
// 二分查找的入口方法。注意泛型类型T必须实现了接口Comparable
// 请求参数为待查找的数组及目标元素,返回参数为目标元素的数组下标(位置)
public static <T extends Comparable<T>> int binarySearch(T[] array, T aim);
定义好泛型的规格后,还得在方法体补充详细的代码逻辑,除了要将比较大小的大于号和小于号换成compareTo方法外,整体的查找过程既可沿用原来的for循环语句,又可以采用严谨的递归方式。
【方法一】:递归方式
封装了二分查找泛型方法的工具类
//二分查找算法的工具类。使用了泛型方法
public class ArrayFind {
private static int count; // 查找次数
// 二分查找的入口方法。注意泛型类型T必须实现了接口Comparable
// 请求参数为待查找的数组及目标元素,返回参数为目标元素的数组下标(位置)
public static <T extends Comparable<T>> int binarySearch(T[] array, T aim) {
count = 0; // 开始查找前先把查找次数清零
return binarySearch(array, 0, array.length - 1, aim);//说白了就是对start、end赋值
}
// 使用递归实现的二分查找
private static <T extends Comparable<T>> int binarySearch(T[] array, int begin, int end, T aim) {
count++; // 查找次数加一
if (begin >= end && aim.compareTo(array[begin])!=0) {
// 起点和终点都重合了还没找到
return -1; // 返回-1表示没找到
}
//int middle = begin + ((end - begin) >> 1);
int middle = (begin + end) / 2; // 计算中间的位置
if (aim.compareTo(array[middle]) == 0) {
// 找到目标值,返回目标值所处的位置
System.out.println("查找次数="+count);
return middle;
} else if (aim.compareTo(array[middle]) < 0) {
// 目标值在前半段,继续查找
return binarySearch(array, begin, middle - 1, aim);
} else {
// 目标值在后半段,继续查找
return binarySearch(array, middle + 1, end, aim