数据结构 -- 二分查找

本文主要梳理了二分查找算法的几种实现思路,基本概念参考 顺序、二分、哈希查找的区别及联系_生成一个大小为10万的有序数组,随机查找一个元素,分别采用顺序查找和二分查找方式-CSDN博客

1、基本概念

(1)前提条件:待查找数据必须有序。

(2)实现方式:在查找过程中,它先和中间的比较,如果等于就直接返回,如果小于就在前半部分继续使用二分法进行查找,如果大于则在后半部分继续使用二分法进行查找。

2、算法实现

2.1 基本版实现

package com.hh.algorithm.find;public class BinarySearch {public static void main(String[] args) {int[] arr = {1,2,4,5,5,6,7,8,9,11,23};System.out.println(BinarySearch.binary(arr, 4));}public static int binary(int[] arr, int key) {int i = 0;int j = arr.length - 1;while (i <= j) {int mid = (i + j) >>> 1;if (key < arr[mid]) {j = mid - 1;} else if (key > arr[mid]) {i = mid + 1;} else {return mid;}}return -1;}}

问题1:为什么是 i<=j ,而不是 i<j?

(1)i==j:意味着 i,j 它们指向的元素也会参与比较;

(2)i<j:只意味着mid 指向的元素参与比较。

问题2:j - ((j - i) >> 1) 与 (i+j)/2都是相加除2,使用后者有没有问题?

当超出 int 的范围时,他会把最高位视为符号位。

代码实现

package com.hh.algorithm.find;public class BinarySearchTest {public static void main(String[] args) {/*同一个二进制数1011 1111 1111 1111 1111 1111 1111 1110没有超出int 范围,默认是:不把最高位视为符号位,代表3221225470超出int 范围,把最高位视为符号位,代表-1073741826所以,当计算结果超出int的范围时,他就会把最高位视为符号位*/int i = 0;int j = Integer.MAX_VALUE - 1;int mid = (j + i) / 2;int mid2 = (i + j) >>> 1;System.out.println("第1轮(j + i) / 2:" + mid);System.out.println("第1轮(j+i)/2:" + mid2);System.out.println("---------------------");i = mid+1;mid = (j + i) / 2;mid2 = (i + j) >>> 1;System.out.println("第2轮(j + i) / 2:" + mid);System.out.println("第2轮(j+i)/2:" + mid2);/*扩展:(1)(j + i) / 2还有另一种写法,也就是 j - (j - i) / 2(2)j - (j - i) / 2 拆开就是 j - j/2 + i/2  --> j/2 + i/2  --> (j + i) / 2*/}
}

运行结果

2.2 平衡版实现

package com.hh.algorithm.find;
/*// 如果待查找数字一直在左边,if那么就会判断比较log(n)次if (key < arr[mid]) {j = mid - 1;} else if (key > arr[mid]) {// 如果待查找数字一直在右边,if那么就会判断比较2log(n)次i = mid + 1;} else {return mid;}解决方式:1.左闭右开的区间,i指向的可能是目标,而j指向的不是目标2.不在循环内找出,等范围内只剩i时,退出循环,在循环外比较 a[i]与target3.循环内的平均比较次数减少了4.时间复杂度    θ(log(n))
*/
public class BinarySearch2 {public static void main(String[] args) {int[] arr = {1,2,4,5,5,6,7,8,9,11,23};System.out.println(BinarySearch2.binary(arr, 4));}public static int binary(int[] arr, int key) {int i = 0;int j = arr.length;while (i + 1 < j) {int mid = (i + j) >>> 1;if (key < arr[mid]) {j = mid;} else{i = mid;}}return (key == arr[i])? i : -1;}}

运行结果

2.3 java版实现

package com.hh.algorithm.find;/*** 下面是java版本的二分查找代码实现,粘贴了底层代码*/
public class BinarySearch3 {public static void main(String[] args) {int[] arr = {1,2,4,5,5,6,7,8,9,11,23};System.out.println(BinarySearch3.binarySearch(arr,4));}public static int binarySearch(int[] a, int key) {return binarySearch0(a, 0, a.length, key);}private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {int low = fromIndex;int high = toIndex - 1;while (low <= high) {int mid = (low + high) >>> 1;int midVal = a[mid];if (midVal < key)low = mid + 1;else if (midVal > key)high = mid - 1;elsereturn mid; // key found}//没找到就返回插入点位置return -(low + 1);  // key not found.}
}

运行结果

2.4 有重复元素的数组,返回左右

package com.hh.algorithm.find;/*** 当该数组有重复元素时,返回最靠左(右)的元素位置*/
public class BinarySearchMost {public static void main(String[] args) {int[] arr = {1,2,4,5,7,7,7,7,11,23};System.out.println(BinarySearchMost.binaryLeft(arr,7));System.out.println(BinarySearchMost.binaryRight(arr,7));}/*返回最靠左的元素索引*/public static int binaryLeft(int[] arr, int key) {int i = 0;int j = arr.length - 1;int candidate = -1;while (i <= j) {int mid = (i + j) >>> 1;if (key < arr[mid]) {j = mid - 1;} else if (key > arr[mid]) {i = mid + 1;} else {candidate = mid;j = mid -1;}}return candidate;}/*返回最靠右的元素索引*/public static int binaryRight(int[] arr, int key) {int i = 0;int j = arr.length - 1;int candidate = -1;while (i <= j) {int mid = (i + j) >>> 1;if (key < arr[mid]) {j = mid - 1;} else if (key > arr[mid]) {i = mid + 1;} else {candidate = mid;i = mid +1;}}return candidate;}
}

运行结果

2.5 没找到返回有意义的值

package com.hh.algorithm.find;/*** 当该数组找不到该元素时,返回大于(小于)等于目标的最靠左(右)的索引位置*/
public class BinarySearchMost2 {public static void main(String[] args) {int[] arr = {1,2,4,5,7,7,7,7,11,23};System.out.println(BinarySearchMost2.binaryLeft(arr,3));System.out.println(BinarySearchMost2.binaryRight(arr,9));}/*返回大于目标的最靠左索引*/public static int binaryLeft(int[] arr, int key) {int i = 0;int j = arr.length - 1;while (i <= j) {int mid = (i + j) >>> 1;if (key <= arr[mid]) {j = mid - 1;} else{i = mid + 1;}}return i;}/*返回最小于目标的最靠右索引*/public static int binaryRight(int[] arr, int key) {int i = 0;int j = arr.length - 1;while (i <= j) {int mid = (i + j) >>> 1;if (key < arr[mid]) {j = mid - 1;} else {i = mid +1;}}return i-1;}
}

运行结果

本文为学习笔记,所参考文章均已附上链接,若有疑问请私信!

创作不易,如果对你有点帮助的话麻烦点个赞支持一下!

新手小白,欢迎留言指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/312164.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT 浅析

GPT 浅析 文章目录 GPT 浅析GPT 1无监督预训练有监督微调任务相关的输入变换 GPT2GPT3 GPT 1 在模型架构上&#xff0c;GPT-1基于Transformer构造&#xff0c;这是因为与其他卷积神经网 络或者循环神经网络相比&#xff0c;Transformer提供了效率更高的方法来处理文本 中的长期…

leetcode hot100_day20

4/14/2024 128.最长连续序列 自己的 这是前两天做一半的题目了。这题给我的教训就是用哈希表的时候一定一定要考虑重复元素的问题&#xff01;&#xff01;&#xff01;&#xff01; 这题让我想到了最长递增子序列&#xff0c;只是名字有点像。子序列和子数组还不一样一个连续…

【HCIP学习】OSPF协议基础

一、OSPF基础 1、技术背景&#xff08;RIP中存在的问题&#xff09; RIP中存在最大跳数为15的限制&#xff0c;不能适应大规模组网 周期性发送全部路由信息&#xff0c;占用大量的带宽资源 路由收敛速度慢 以跳数作为度量值 存在路由环路可能性 每隔30秒更新 2、OSPF协议…

错误分析 (Machine Learning研习十九)

错误分析 您将探索数据准备选项&#xff0c;尝试多个模型&#xff0c;筛选出最佳模型&#xff0c;使用 Grid SearchCV微调其超参数&#xff0c;并尽可能实现自动化。在此&#xff0c;我们假设您已经找到了一个有前途的模型&#xff0c;并希望找到改进它的方法。其中一种方法就…

第九届少儿模特明星盛典 全球赛推广大使『武家翔』精彩回顾

2024年1月30日-2月1日&#xff0c;魔都上海迎来了龙年第一场“少儿形体行业美育春晚”&#xff01;由IPA模特委员会主办的第九届少儿模特明星盛典全球总决赛圆满收官&#xff01;近2000名少儿模特选手从五湖四海而来&#xff0c;决战寒假这场高水准&#xff0c;高人气&#xff…

uni-app学习

目录 一、安装HBuilderX 二、创第一个uni-app 三、项目目录和文件作用 四、全局配置文件&#xff08;pages.json&#xff09; 4.1 globalStyle&#xff08;全局样式&#xff09; 导航栏&#xff1a;背景颜色、标题颜色、标题文本 导航栏&#xff1a;开启下拉刷新、下拉背…

Axure实现导航栏的展开与收缩

Axure实现导航栏的展开与收缩 一、概要介绍二、设计思路三、Axure制作导航栏四、技术细节五、小结 一、概要介绍 使用场景一般是B端后台系统需要以导航栏的展开与收缩实现原型的动态交互&#xff0c;主要使用区域是左边或者顶部的导航栏展开与收缩&#xff0c;同一级导航下的小…

ActiveMQ 01 消息中间件jmsMQ

消息中间件之ActiveMQ 01 什么是JMS MQ 全称&#xff1a;Java MessageService 中文&#xff1a;Java 消息服务。 JMS 是 Java 的一套 API 标准&#xff0c;最初的目的是为了使应用程序能够访问现有的 MOM 系 统&#xff08;MOM 是 MessageOriented Middleware 的英文缩写&am…

Servlet测试1

通过按钮提交get,post请求&#xff0c;并且后端响应数据&#xff0c;显示到前端 当点击get按钮时 是发起Get请求 后端接收到Get请求后&#xff0c;把数据写入到body内 当点击pst按钮时 是发起Post请求 后端接收到Post请求后&#xff0c;把数据写入到body内 之后前端就从bod…

Python 物联网入门指南(七)

原文&#xff1a;zh.annas-archive.org/md5/4fe4273add75ed738e70f3d05e428b06 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第二十四章&#xff1a;基本开关 到目前为止一定是一段史诗般的旅程&#xff01;回想一下你开始阅读这本书的时候&#xff0c;你是否曾想象…

HarmonyOS开发实战:【亲子拼图游戏】

概述 本篇Codelab是基于TS扩展的声明式开发范式编程语言编写的一个分布式益智拼图游戏&#xff0c;可以两台设备同时开启一局拼图游戏&#xff0c;每次点击九宫格内的图片&#xff0c;都会同步更新两台设备的图片位置。效果图如下&#xff1a; 说明&#xff1a; 本示例涉及使…

项目管理利器 Git

一、序言 今天聊聊 Git。 二、开发的问题 在开发项目时&#xff0c;我们的代码都是直接放在本地的机器上的。如果本地机器出现了问题&#xff0c;怎么办&#xff1f;在企业中&#xff0c;开发项目都是团队协作&#xff0c;一个团队共同维护一个项目该如何处理&#xff1f;团…

C++11(下篇)

文章目录 C111. 模版的可变参数1.1 模版参数包的使用 2. lambda表达式2.1 Lambda表达式语法捕获列表说明 2.2 lambda的底层 3. 包装器3.1 function包装器3.2 bind 4. 线程库4.1 thread类4.2 mutex类4.3 atomic类4.4 condition_variable类 C11 1. 模版的可变参数 C11支持模版的…

python 列表对象函数

对象函数必须通过一个对象调用。 列表名.函数名() append() 将某一个元素对象添加在列表的表尾 如果添加的是其他的序列&#xff0c;该序列也会被看成是一个数据对象 count() 统计列表当中 某一个元素出现的次数 extend() 在当前列表中 将传入的其他序列的元素添加在表尾…

自定义类似微信效果Preference

1. 为自定义Preference 添加背景&#xff1a;custom_preference_background.xml <?xml version"1.0" encoding"utf-8"?> <selector xmlns:android"http://schemas.android.com/apk/res/android"><item><shape android:s…

vue:如何通过两个点的经纬度进行距离的计算(很简单)

首先假设从api获取到了自己的纬经度和别人的纬经度 首先有一个概念需要说一下 地球半径 由于地球不是一个完美的球体&#xff0c;所以并不能用一个特别准确的值来表示地球的实际半径&#xff0c;不过由于地球的形状很接近球体&#xff0c;用[6357km] 到 [6378km]的范围值可以…

Python-VBA函数之旅-eval函数

目录 一、eval函数的常见应用场景&#xff1a; 二、eval函数安全使用注意事项&#xff1a; 三、eval函数与exec函数对比分析&#xff1a; 1、eval函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、相关文章&#xff1a; 个人主页&#xff1a;ht…

RAG (Retrieval Augmented Generation) 结合 LlamaIndex、Elasticsearch 和 Mistral

作者&#xff1a;Srikanth Manvi 在这篇文章中&#xff0c;我们将讨论如何使用 RAG 技术&#xff08;检索增强生成&#xff09;和 Elasticsearch 作为向量数据库来实现问答体验。我们将使用 LlamaIndex 和本地运行的 Mistral LLM。 在开始之前&#xff0c;我们将先了解一些术…

文献学习-37-动态场景中任意形状针的单目 3D 位姿估计:一种高效的视觉学习和几何建模方法

On the Monocular 3D Pose Estimation for Arbitrary Shaped Needle in Dynamic Scenes: An Efficient Visual Learning and Geometry Modeling Approach Authors: Bin Li,† , Student Member, IEEE, Bo Lu,† , Member, IEEE, Hongbin Lin, Yaxiang Wang, Fangxun Zhong, Me…

OpenCV基本图像处理操作(六)——直方图与模版匹配

直方图 cv2.calcHist(images,channels,mask,histSize,ranges) images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的…