二分查找法是将数据折半,小于中间值就找小于中间值区间的数据,大于中间值就找大于中间值区间的数据,这样就大大的增加了效率,可以更快速的查找到指定数据,就是缺点必须是有序的,但是现在实现排序很方便也很高效倒也不是瓶颈,无序的话二分查找也体现不了其意义所在,那么接下来就详细讲解二分查找
1.二分查找概念
二分查找实际上是不断地将有序数据集进行对半分割,并检查每个分区地中间元素。
2.二分查找特点
- 二分查找操作地数据集是一个有序的数据集
- 二分查找能应用于任何类型的数据,只要能将这些数据按照某种规则进行排序
- 当待搜索的集合是相对静态(静态指的是不是动态的数据)的数据集时,此时使用二分查找是最好的选择。
- 复杂度是O(log n),n为要查找的元素个数
3.二分查找原理图
此实现是通过low和high的变量值控制循环来查找
1.首先将low设置为0,high设置为数组长度-1
2.循环迭代的过程中将middle(中间值)设置为low和high区域的中间值
3.判断如果目标值比middle元素值小,那么high移动到middle前一个位置元素上
4.判断如果目标值比middle元素值大,那么low移动到middle后一个位置元素上。
5.依次类推,直到判断相等,值找到。
4.二分查找法代码实现
package com.test.binarySearch;
/**
* 非递归二分查找和递归二分查找的demo
* 二分查找:二分查找必须是有序的集合,进行对半分割查找,并检查每个分区地中间元素
* 此实现是通过low和high的变量值控制循环来查找
* 1.首先将low设置为0,high设置为数组长度-1
* 2.循环迭代的过程中将middle(中间值)设置为low和high区域的中间值
* 3.判断如果目标值比middle元素值小,那么high移动到middle前一个位置元素上
* 4.判断如果目标值比middle元素值大,那么low移动到middle后一个位置元素上。
* 5.依次类推,直到判断相等,值找到。
*
* @Author df
* @Date 2019/9/2 9:39
* @Version 1.0
*/
public class towBinarySearch {
public static void main(String[] args) {
Integer[] intArray = {23, 30, 44, 56, 60, 61};
System.out.println(NonRecursive(intArray, 56));
//System.out.println(recursive(intArray, 0, intArray.length - 1, 30));
}
/**
* 非递归形式的二分查找
*
* @param intArray 整型数组
* @param keyValue 需要比较的数
* @return
*/
public static int NonRecursive(Integer[] intArray, int keyValue) {
// 第一个位置.
int low = 0;
// 最高位置,数组长度-1,因为下标是从0开始的。
int high = intArray.length - 1;
while (low <= high) {
// 中间位置计算,low+最高位置减去最低位置,右移一位,相当于除2.也可以用(high+low)/2
int middle = low + ((high - low) >> 1);
// 与最中间的数字进行判断,是否相等,相等的话就返回对应的数组下标。
if (keyValue == intArray[middle]) {
return middle;
} else if (keyValue < intArray[middle]) {
// 如果比较数小于当前中间位置的话移动最高层的“指针”
// 此处移动high高指针是因为比对的值小于,就需要查找左半部分的数据
high = middle - 1;
} else {
low = middle + 1;
}
}
return -1;
}
/**
* 递归形式的二分查找
*
* @param intArray 整型数组
* @param low 最开始的下标
* @param high 最高的坐标
* @param keyValue 需要比较的数
* @return
*/
public static int recursive(Integer[] intArray, int low, int high, int keyValue) {
if (low <= high) {
int middle = (low + high) / 2;
// 与基准值进行比较,相等就是找到想要的数据
if (keyValue == intArray[middle]) {
return middle;
}
// 小于基准值右指针向左移动一格
if (keyValue < intArray[middle]) {
return recursive(intArray, low, middle - 1, keyValue);
}
// 大于基准值左指针向右移动一格
if (keyValue > intArray[middle]) {
return recursive(intArray, middle + 1, high, keyValue);
}
} else {
return -1;// 什么都查找不到的话。
}
return -1;
}
}
二分查找法就介绍这么多,下次见