Java二分查找算法实例详解
作者:bjpowernode 发布时间:2022-07-09 14:33:55
在本文中,我们将介绍二进制搜索相对于简单线性搜索的优势,并介绍它在 Java 中的实现。
1. 需要有效的搜索
假设我们在wine-selling业务和数以百万计的买家每天都访问我们的应用程序。
通过我们的应用程序,客户可以过滤掉物品价格低于n美元,从搜索结果中选择一个瓶子,并将它们添加到购物车。我们有成千上万的用户寻求葡萄酒价格限制每一秒。需要快速的结果。
后端,我们的算法运行的线性搜索整个列表葡萄酒比较价格限制输入的客户提供的价格每一个酒瓶在列表中。
然后,它返回物品的价格小于或等于价格限制。这个线性搜索时间复杂度为O (n)。
这意味着我们系统中的酒瓶数量越多,所需的时间就越多。搜索时间与引入的新项目的数量成正比。
如果我们开始按排序顺序保存项目并使用二进制搜索搜索项目,我们可以实现O(log n)的复杂度。
对于二分搜索,搜索结果所花费的时间自然会随着数据集的大小而增加,但不会成比例地增加。
2. 二分查找
简单来说,算法将键值与数组的中间元素进行比较;如果它们不相等,则删除不能包含密钥的一半,并继续搜索剩余的一半,直到成功。
请记住 - 这里的关键方面是数组已经排序。
如果搜索以剩余的一半为空而结束,则该键不在数组中。
(1)迭代实现
public int runBinarySearchIteratively(
int[] sortedArray, int key, int low, int high) {
int index = Integer.MAX_VALUE;
while (low <= high) {
int mid = low + ((high - low) / 2);
if (sortedArray[mid] < key) {
low = mid + 1;
} else if (sortedArray[mid] > key) {
high = mid - 1;
} else if (sortedArray[mid] == key) {
index = mid;
break;
}
}
return index;
}
runBinarySearchIteratively方法将sortedArray、key和 sortedArray 的低索引和高索引作为参数。当方法第一次运行时, sortedArray的第一个索引low为 0,而sortedArray的最后一个索引high等于其长度 - 1。
中间是sortedArray的中间索引。现在算法运行一个while循环,将键与sortedArray的中间索引的数组值进行比较。
注意中间索引是如何生成的(int mid = low + ((high – low) / 2)。这是为了适应非常大的数组。如果中间索引是通过获取中间索引(int mid = (low + high) / 2) ,包含 2 30 个或更多元素的数组可能会发生溢出,因为low + high的总和很容易超过最大正int值。
(2)递归实现
现在,让我们看看一个简单的递归实现:
public int runBinarySearchRecursively(
int[] sortedArray, int key, int low, int high) {
int middle = low + ((high - low) / 2);
if (high < low) {
return -1;
}
if (key == sortedArray[middle]) {
return middle;
} else if (key < sortedArray[middle]) {
return runBinarySearchRecursively(
sortedArray, key, low, middle - 1);
} else {
return runBinarySearchRecursively(
sortedArray, key, middle + 1, high);
}
}
runBinarySearchRecursively方法接受sortedArray、键、sortedArray的低索引和高索引。
(3)使用数组。二进制搜索()
int index = Arrays.binarySearch(sortedArray, key);
将在整数数组中搜索的 sortedArray和int key作为参数传递给Java Arrays类的binarySearch方法。
(4)使用集合。二进制搜索()
int index = Collections.binarySearch(sortedList, key);
sortedList &整数键,搜索列表中的整数对象,作为参数传递到binarySearch Java集合类的方法。
(5)性能
是否使用递归迭代的方法编写的算法主要是一个个人喜好问题。但仍有一些观点我们应该意识到:
1)慢递归可以维护一个堆栈的开销和通常要占用更多的记忆空间
2)递归不是stack-friendly。它可能导致StackOverflowException当处理大数据集
3)递归添加清晰的代码,使其较短的迭代方法相比
理想情况下,一个二叉搜索将执行更少数量的比较与一个线性搜索大的n, n为较小的值,值的线性搜索可以执行比二进制搜索。
每个人都应该知道这个分析是理论和可能取决于上下文。
此外,二分搜索算法需要一个排序的数据集,它也有它的成本。如果我们使用归并排序算法对数据进行排序,则会在我们的代码中增加n log n的额外复杂度。
知识点扩展:
二分算法步骤描述
① 首先确定整个查找区间的中间位置 mid = ( left + right )/ 2
② 用待查关键字值与中间位置的关键字值进行比较;
若相等,则查找成功
若大于,则在后(右)半个区域继续进行折半查找
若小于,则在前(左)半个区域继续进行折半查找
③ 对确定的缩小区域再按折半公式,重复上述步骤。
最后,得到结果:要么查找成功, 要么查找失败。折半查找的存储结构采用一维数组存放。 折半查找算法举例
对给定数列(有序){ 3,5,11,17,21,23,28,30,32,50,64,78,81,95,101},按折半查找算法,查找关键字值为81的数据元素。
来源:http://www.bjpowernode.com/javazixun/10186.html


猜你喜欢
- 1.导入 maven依赖 <dependency> <groupId>org.spring
- 目录什么是Feign为什么使用Feign为什么要使用HTTP client为什么要使用Feign如何使用Feign项目环境说明引入依赖入门例
- 本文实例讲述了C#基于UDP进行异步通信的方法。分享给大家供大家参考。具体如下:服务器端:using System;using System
- 1、首先创建一个按钮<Buttonandroid:id="@+id/click"android:layout_wi
- 一、前言滚动条一般用于加载进度,我们在看视频的时候或者在浏览网页的时候经常能看到加载进度的页面。在程序开发中,默认的进度加载样式可能跟程序风
- Activity中Toast的使用Toast.makeText(this,"ADD",Toast.LENGTH_SHOR
- final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。 通常final定义的变量为常量。如:final double
- 涉及知识点在本示例中,从数据绑定,到数据展示,涉及知识点如下所示:DataGrid,要WPF提供的进行二维数据展示在列表控件,默认功能非常简
- @Async注解如何实现方法异步处理大批量数据的时候,效率很慢。所以考虑一下使用多线程。刚开始自己手写的一套,用了线程池启动固定的线程数进行
- 先给大家展示下效果图:废话不多说了,下面通过示例代码给大家介绍checkbox 多项选择当前的position信息提交,具体代码如下所示:p
- 一.认识IO1.IO的分类(1)BIO:同步阻塞IO(2)NIO:同步非阻塞IO(3)AIO:异步阻塞IO注意: 这里主要介绍BIO2.IO
- 在8 里面Lambda是最火的主题,不仅仅是因为语法的改变,更重要的是带来了函数式编程的思想,我觉得优秀的程序员,有必要学习一下函数式编程的
- strings.xml 有很多需要注意的地方和一些小技巧,知道了这些可以让你的 Android 应用更加规范易用,感兴趣的小伙伴们可以参考一
- 最近开发了比较多的接口,因为没有可参考的案例,所以一开始一直按照我的理解进行开发。开发多了发现自己每个结果都写了相同的代码:try() {}
- 1、用ASCII码判断在 ASCII码表中,英文的范围是0-127,而汉字则是大于127,具体代码如下:string text = &quo
- 本文实例讲述了java编程调用存储过程中得到新增记录id号的实现方法。分享给大家供大家参考,具体如下:关于ms sql server2000
- 方式1:dependency 本地jar包<dependency> <groupId>com.jouyp
- 一、前言在Java编码中,我们经常会遇到List与数组的转换,包括对象List与对象数组的转换,以及对象List与基本数据类型数组的转换,下
- 效果图如下:类注释:方法注释:idea不会默认帮我们设置,所以需要手动设置。1:IDEA中在创建类时会自动给添加注释打开idea,操作Fil
- 本文以实例代码实现了C#根据数字序号输出星期几,用户可通过输入数字0~6,输出星期各天的英语单词,程序中主要是演示if语句和switch语句