Java 二分法检索算法代码实现详解
作者:失控的狗蛋~ 发布时间:2022-01-05 19:13:24
一,二分法检索算法介绍
二分法检索(binary search)又称折半检索,二分法检索的基本思想是设字典中的元素从小到大有序地存放在数组(array)中。是最常用的搜索算法之一,这主要是由于其搜索时间短。
二,二分法检索算法思路
这种搜索使用分而治之方法,并且需要事先对数据集进行排序。
它将输入集合分为相等的两半,并且每次迭代都将目标元素与中间元素进行比较。
如果找到该元素,则搜索结束。否则,我们根据目标元素是小于还是大于中间元素,通过划分并选择适当的数组分区来继续寻找元素。
这就是为什么对Binary Search有一个排序的集合很重要的原因。
当firstIndex(我们的指针)经过lastIndex(最后一个元素)时,搜索将终止,这意味着我们已经搜索了整个数组,并且该元素不存在。
有两种方法可以实现此算法- 迭代和递归。
这里不应该是关于时间和空间这两个实现之间复杂的差异,虽然这不成立于所有语言。
三,二分法检索算法代码实现
迭代式
首先让我们看一下迭代方法:
public class SearchAlgorithms {
/**
*迭代方法
* @param arr
* @param elementToSearch
* @return
*/
public static int binarySearch(int arr[], int elementToSearch) {
int firstIndex = 0;
int lastIndex = arr.length - 1;
// 终止条件(元素不存在)
while(firstIndex <= lastIndex) {
int middleIndex = (firstIndex + lastIndex) / 2;
// 如果中间元素是我们的目标元素,那么返回它的索引
if (arr[middleIndex] == elementToSearch) {
return middleIndex;
}
// 如果中间的元素比较小
// 将我们的指数指向中间+1,不考虑前半部分
else if (arr[middleIndex] < elementToSearch)
firstIndex = middleIndex + 1;
// 如果中间的元素更大
// 将我们的指数指向中间1,不考虑下半部分
else if (arr[middleIndex] > elementToSearch)
lastIndex = middleIndex - 1;
}
return -1;
}
/**
* 用于打印结果
* @param targetParameter
* @param index
*/
public static void print(int targetParameter, int index) {
if (index == -1){
System.out.println(targetParameter + " 未找到");
}
else {
System.out.println(targetParameter + " 搜索结果为: " + index);
}
}
//测试一下
public static void main(String[] args) {
int index = binarySearch(new int[]{89, 57, 91, 47, 95, 3, 27, 22, 67, 99}, 67);
print(67, index);
}
}
输出:
递归的
现在让我们看一下递归实现:
递归方法的区别在于,一旦获得新分区,我们便会调用方法本身。在迭代方法中,每当确定新分区时,我们都会修改第一个和最后一个元素,并在同一循环中重复该过程。
这里的另一个区别是递归调用被推入方法调用堆栈,并且每个递归调用占用一个空间单位。
我们可以像这样使用这种算法:
public class SearchAlgorithms {
/**
*递归方法
* @param arr
* @param elementToSearch
* @return
*/
public static int recursiveBinarySearch(int arr[], int firstElement, int lastElement, int elementToSearch) {
// 结束条件
if (lastElement >= firstElement) {
int mid = firstElement + (lastElement - firstElement) / 2;
// 如果中间元素是我们的目标元素,那么返回它的索引
if (arr[mid] == elementToSearch)
return mid;
// 如果中间元素大于目标元素
if (arr[mid] > elementToSearch)
return recursiveBinarySearch(arr, firstElement, mid - 1, elementToSearch);
return recursiveBinarySearch(arr, mid + 1, lastElement, elementToSearch);
}
return -1;
}
/**
* 用于打印结果
* @param targetParameter
* @param index
*/
public static void print(int targetParameter, int index) {
if (index == -1){
System.out.println(targetParameter + " 未找到");
}
else {
System.out.println(targetParameter + " 搜索结果为: " + index);
}
}
//测试一下
public static void main(String[] args) {
int index = recursiveBinarySearch(new int[]{3, 22, 27, 47, 57, 67, 89, 91, 95, 99}, 0, 10, 67);
print(67, index);
}
}
输出:
四,以算法时间复杂度和空间复杂度总结算法。
时间复杂度
由于二进制搜索每次将其时间复杂度为O(log(N))时都会将数组分为两半。此时间复杂度是线性搜索O(N)时间复杂度的显着改进。
空间复杂度
此搜索仅需要一个空间单位即可存储要搜索的元素。因此,其空间复杂度为O(1)。
如果二分法检索是递归实现的,则需要将对该方法的调用存储在堆栈中。在最坏的情况下,这可能需要O(log(N))空间。
它是大多数用于搜索的库中最常用的搜索算法,二分法检索树也被许多存储排序数据的数据结构所使用。
该Arrays.binarySearch方法中的Java API也实现了二进制搜索哦。
来源:https://blog.csdn.net/Summer_Lyf/article/details/103906145


猜你喜欢
- 日常的开发中经常会需要用到自定义View,这次刚好有个需求,需要用到带有节点的进度条。东西很简单直接继承View就行了。首先定义一些需要的属
- 本文以C#代码为例介绍如何实现将彩色PDF文件转为灰度(黑白)的PDF文件,即 将PDF文档里面的彩色图片或者文字等通过调用PdfGrayC
- 目录效果展示实现原理实现步骤完整代码展示效果展示实现原理首先需要生成绘制小花的坐标点,坐标点的横坐标是根据控件的宽度随机生成的,而纵坐标则设
- IDEA maven项目中刷新依赖的方法IDEA maven项目中刷新依赖分为自动刷新 和 手动刷新 两种!自动刷新File-Setting
- 本文主要介绍了WPF中常用的鼠标事件、键盘事件以及注意事项,同时使用一个案例讲解了拓展事件。除此之外,本文还讲述如何用行为(Behavior
- 图的实际应用在现实生活中,有许多应用场景会包含很多点以及点点之间的连接,而这些应用场景我们都可以用即将要学习的图这种数据结构去解决。地图:我
- 本文实例为大家分享了C# Winform 自动更新程序,供大家参考,具体内容如下第一步:检查更新检查更新其实无非就是去比较更新包的版本和本地
- 使用flatMap列出子目录前面已经看到如何列出指定目录下的文件了。我们再来看下如何遍历指定目录的直接子目录(深度为1),先实现一个简单的版
- 在学习 Spring Mvc 过程中,有必要来先了解几个关键参数:@Controller:在类上注解,则此类将编程一个控制器,在项目启动 S
- 前言一般在c++中没有使用的变量会有警告,C#中也有,在QT中我们利用Q_UNSED可以直接消除这些警告,那么我们在C#中该如何做才能消除这
- 本文实例为大家分享了Java NIO实战之多人聊天室的具体代码,供大家参考,具体内容如下NIO服务端public class NioServ
- Java对象为什么需要被序列化序列化能够将对象转为二进制流,对象就可以方便的在网络中被传输和保存。实现序列化的方式实现Serializabl
- 先看看效果图:中间的圆形头像和光环波形讲解请看:https://www.jb51.net/article/96508.htm周围的气泡布局,
- 目录多开理论基础多开实现原理解析代码实现:多开包名代码实现:多用户总结多开理论基础app多开常用于做一些不合法的事情,如高羊毛,黑灰产,甚至
- 效果 使用compile 'site.gemus:openingstartanimation:1.0.0' //在gra
- 本文实例为大家分享了flutter Container容器实现圆角边框的具体代码,供大家参考,具体内容如下在这里使用 Container 容
- 本文实例为大家分享了Android实现拼图小游戏的具体代码,供大家参考,具体内容如下目标效果: 1.activity_main.x
- 昨天写了一个关于Excel文件处理的脚本,在字符串匹配功能上总是出现多余不正确的匹配,debug调试之后,发现一个坑。------->
- 1.easy-captcha工具包生成验证码的方式有许多种,这里选择的是easy-captcha工具包。github开原地址为:easy-c
- 概述 ScrollView也是一个容器,它是FrameLayout的子类,它的主要作用就是将超出物理屏幕的内容显示