二分查找
适用于数据量较大时,但是数据需要先排好顺序
说明
元素必须是有序的,如果是无序的则要先进行排序操作。
基本思想
也称为是折半查找,属于有序查找算法。 用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功; 若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行, 直到查找到或查找结束发现表中没有这样的结点。
例如,在{53,14,99,38,45,87,10,81,47,21}这个查找表使用折半查找算法查找数据之前,需要首先对该表中的数据按照所查的关键字进行排序:{10,14,21,38,45,47,53,81,87,99},采用折半查找算法查找关键字为 47 的过程为:
复杂度分析
最坏情况下,关键词比较次数为log2(n+1), 且期望时间复杂度为O(log2n);
折半查找的前提条件是需要有序表顺序存储,对于静态查找表, 一次排序后不再变化,折半查找能得到不错的效率。 但对于需要频繁执行插入或删除操作的数据集来说, 维护有序的排序会带来不小的工作量,那就不建议使用。——《大话数据结构》
代码实现
package algorithm.seek;
/**
* 二分法查找: 适用于数据量较大时,但是数据需要先排好顺序
*/
public class BinarySearch {
/**
* @param array 数集合
* @param target 目标数
*/
private static int binary(int[] array, int target) {
int low = 0;
int high = array.length - 1;
while (low <= high) {
int middle = (low + high) / 2;
if (target == array[middle]) {
return middle;
}
if (target > array[middle]) {
low = middle + 1;
}
if (target < array[middle]) {
high = middle - 1;
}
}
// 没找到返回 -1
return -1;
}
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int value = binary(a, 9);
System.out.println(value);
}
}