【查找算法】二分查找

一:二分查找

1.1 基本概念

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

1.2 原理

  1. 查找的目标数据元素必须是有序的。没有顺序的数据,二分法就失去意义。
  2. 数据元素通常是数值型,可以比较大小。
  3. 将目标元素和查找范围的中间值做比较(如果目标元素=中间值,查找结束),将目标元素分到较大/或者较小的一组。
  4. 通过分组,可以将查找范围缩小一半。
  5. 重复第三步,直到目标元素=新的范围的中间值,查找结束。

1.3 基本思想

首先用要查找的关键字key与中间位置的结点的关键字相比较,这个中间结点把线性表分成了两个子表,若比较结果相等则查找完成;若不相等,再根据k与该中间节点关键字的的比较大小来去确定下一步查找哪个子表(如果我们把一个线性表想成是水平的,如果key值大于中间节点,则在右边的子表继续查找;如果key值小于中间值,则在左边的子表继续查找),这样递归下去,直到找到满足条件的节点或者该线性表中没有这样的节点。

1.4 图解

第一步:
在这里插入图片描述
第二步:
在这里插入图片描述
第三步:
在这里插入图片描述

1.5 优缺点

优点:

  • 比较次数少,查找速度快,平均性能好。

缺点:

  • 必须要求待查表为有序表(若为无序数组,分成两份查找没有意义,排序本身也要耗费时间);
  • 插入删除困难(曾删操作需要移动大量的节点)

二:时间以及空间复杂度

2.1 时间复杂度分析

最坏的情况下:两种方式时间复杂度一样:O(log2 N)
最好情况下: O(1)

2.2 空间复杂度分析

算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数

2.2.1 循环方式

由于辅助空间是常数级别的所以: 空间复杂度是O(1);

2.2.2 递归方式

递归的次数和深度都是log2 N,每次所需要的辅助空间都是常数级别的:空间复杂度:O(log2N )

三:代码实现

3.1 基本写法

/*** 二分查找* 注意:使用二分查找必须保证该数组是有序的*/
public class BinarySearch {public static void main(String[] args) {int[] array = {1, 8, 10, 89, 1000, 1234};int index = binarySearch(array, 0, array.length - 1, 1);System.out.println(index);}/*** 二分查找算法** @param array     原始数组* @param right     右节点* @param left      左节点* @param findValue 需要查找的值* @return 需要查找值的下标,如果没找到就返回-1*/public static int binarySearch(int[] array, int right, int left, int findValue) {//获取中间值的下标int middle = (right + left) / 2;//获取中间值int middleValue = array[middle];//当findValue小于最小值或者大于最大值的时候,表示没有找到当前数,返回-1表示未找到if (findValue < array[0] || findValue > array[array.length - 1] || left > right) {return -1;}if (findValue > middleValue) {//如果需要查找的值大于中间值,则向右递归return binarySearch(array, middle + 1, left, findValue);} else if (findValue < middleValue) {//如果需要查找的值小于中间值,则向左递归return binarySearch(array, right, middle - 1, findValue);} else {return middle;}}}

3.2 代码升级

问题:当一个有序数组中,有多个相同的数值时,如:{1,8, 10, 89, 1000, 1000,1234} 。如何将所有的数值都查找到,比如这里的 1000

package com.sysg.dataStructuresAndAlgorithms.find;import java.util.ArrayList;
import java.util.List;/*** 二分查找* 注意:使用二分查找必须保证该数组是有序的*/
public class BinarySearch {public static void main(String[] args) {int[] array = {1, 8, 10, 89, 1000, 1000, 1000, 1000, 1234};int index = binarySearch(array, 0, array.length - 1, 1000);System.out.println(index);List<Integer> indexPlus = binarySearchPlus(array, 0, array.length - 1, 1000);System.out.println(indexPlus);}/*** 二分查找算法(基础版本)** @param array     原始数组* @param right     右节点* @param left      左节点* @param findValue 需要查找的值* @return 需要查找值的下标,如果没找到就返回-1*/public static int binarySearch(int[] array, int left, int right, int findValue) {//获取中间值的下标int middle = (right + left) / 2;//获取中间值int middleValue = array[middle];//当findValue小于最小值或者大于最大值的时候,表示没有找到当前数,返回-1表示未找到if (findValue < array[0] || findValue > array[array.length - 1] || left > right) {return -1;}if (findValue > middleValue) {//如果需要查找的值大于中间值,则向右递归return binarySearch(array, middle + 1, right, findValue);} else if (findValue < middleValue) {//如果需要查找的值小于中间值,则向左递归return binarySearch(array, left, middle - 1, findValue);} else {return middle;}}/*** 二分查找算法(升级版本)* 问题:当一个有序数组中,有多个相同的数值时,如:{1,8, 10, 89, 1000, 1000,1234} 。如何将所有的数值都查找到,比如这里的 1000* 思路分析:* 1.再找到middle的索引值后不要马上就返回* 2.向索引值的左边进行扫描,将所有符合条件的索引下标放入到arrayList当中* 3.向索引值的右边进行扫描,将所有符合条件的索引下标放入到arrayList当中* 4.最后返会arrayList** @param array     原始数组* @param right     右节点* @param left      左节点* @param findValue 需要查找的值* @return 需要查找值的下标,如果没找到就返回-1*/public static List<Integer> binarySearchPlus(int[] array, int left, int right, int findValue) {//获取中间值的下标int middle = (right + left) / 2;//获取中间值int middleValue = array[middle];//当findValue小于最小值或者大于最大值的时候,表示没有找到当前数,返回-1表示未找到if (findValue < array[0] || findValue > array[array.length - 1] || left > right) {return new ArrayList<>();}if (findValue > middleValue) {//如果需要查找的值大于中间值,则向右递归return binarySearchPlus(array, middle + 1, right, findValue);} else if (findValue < middleValue) {//如果需要查找的值小于中间值,则向左递归return binarySearchPlus(array, left, middle - 1, findValue);} else {List<Integer> resultIndexList = new ArrayList<>();//向左边扫描//定义一个临时的值来记录middle左边的值int temp = middle - 1;//退出while (temp >= 0 && array[temp] == findValue) {//否则就将temp放入到arrayList当中resultIndexList.add(temp);//将temp左移继续判断temp -= 1;}resultIndexList.add(middle);//向右边扫描temp = middle + 1;//退出while (temp <= array.length - 1 && array[temp] == findValue) {//否则就将temp放入到arrayList当中resultIndexList.add(temp);//将temp左移继续判断temp++;}return resultIndexList;}}}

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

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

相关文章

MySQL 8.0.35 企业版安装和启用TDE插件keyring_encrypted_file

本文主要记录MySQL企业版TDE插件keyring_encrypted_file的安装和使用。 TDE说明 TDE( Transparent Data Encryption,透明数据加密) 指的是无需修改应用就可以实现数据的加解密&#xff0c;在数据写磁盘的时候加密&#xff0c;读的时候自动解密。加密后其他人即使能够访问数据库…

Progressive Widening

下面的解释来源于论文《Monte Carlo Tree Search With Iteratively Refining State Abstractions》&#xff0c;因为这篇论文的重点不是Progressive Widening&#xff0c;所以就不全文学习了&#xff0c;只摘抄其中关于Progressive Widening的部分。 Progressive Widening&…

蓝牙耳机和笔记本电脑配对连接上了,播放设备里没有显示蓝牙耳机这个设备,选不了输出设备

环境&#xff1a; WIN10 杂牌蓝牙耳机6s 问题描述&#xff1a; 蓝牙耳机和笔记本电脑配对连接上了&#xff0c;播放设备里没有显示蓝牙耳机这个设备&#xff0c;选不了输出设备 解决方案&#xff1a; 1.打开设备和打印机&#xff0c;找到这个设备 2.选中这个设备&#…

Nacos配置管理

Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#xff0c;可以集中管理所有…

5.测试教程 - 进阶篇

文章目录 1.按测试对像划分1.1**界面测试**1.2**可靠性测试**1.3**容错性测试**1.4**文档测试**1.5**兼容性测试**1.6**易用性测试**1.7**安装卸载测试**1.8**安全测试**1.9**性能测试**1.10**内存泄漏测试** 2.按是否查看代码划分2.1黑盒测试(Black-box Testing)2.2白盒测试(W…

Scratch 第十六课-弹珠台游戏

第十六课-弹珠台游戏 大家好&#xff0c;今天我们一起做一款弹珠台scratch游戏&#xff0c;我们也可以叫它弹球游戏&#xff01;这款游戏在刚出来的时候非常火爆。小朋友们要认真学习下&#xff01; 这节课的学习目标 物体碰撞如何处理转向问题。复习键盘对角色的控制方式。…

软件开发人员从0到1实现物联网项目:技术调研

前言 春节返乡之际&#xff0c;发现老家县城竟然开了近十家棋牌室。巧的是朋友也有意涉足&#xff0c;便咨询我自助棋牌室的软件投入成本。作为程序员的我&#xff0c;在思考了自助棋牌室背后的技术需求后&#xff0c;嗅到了一丝丝商机&#xff1a;何不自己开发一个自助棋牌室…

YOLOV9训练集制作+Train+Val记录

一、YOLO数据集格式分布 在YOLO中&#xff0c;数据集的分布如图&#xff0c;在dataset文件夹下有imags&#xff08;图片&#xff09;和labels&#xff08;标签&#xff09;。在images和labels文件夹下又分别存放三个文件夹&#xff0c;分别对应测试集、训练集、验证集&#xff…

2023全球软件开发大会-上海站:探索技术前沿,共筑未来软件生态(附大会核心PPT下载)

随着信息技术的迅猛发展&#xff0c;全球软件开发大会&#xff08;QCon&#xff09;已成为软件行业最具影响力的年度盛会之一。2023年&#xff0c;QCon再次来到上海&#xff0c;汇聚了众多业界精英、技术领袖和开发者&#xff0c;共同探讨软件开发的最新趋势和实践。 一、大会…

Frontend - Boostrap 消息弹窗

目录 一、下载 &#xff08;一&#xff09;中文官网 &#xff08;二&#xff09;bootstrap v3 依赖 jQuery 插件 二、解压并安装 &#xff08;一&#xff09;解压 1. 压缩包解压 2. 简化文件 &#xff08;二&#xff09;安装 三、配置 &#xff08;一&#xff09;bas…

【重要公告】对BSV警报系统AS的释义

​​发表时间&#xff1a;2024年2月15日 由BSV区块链协会开发并管理的BSV警报系统&#xff08;Alert System&#xff0c;以下简称“AS”&#xff09;是BSV网络的重要组件。它是一个复杂的系统&#xff0c;主要职能是在BSV区块链网络内发布信息。这些信息通常与网络访问规则NAR相…

深入了解 JavaScript 混淆加密和环境检测

JavaScript混淆加密是一种通过修改代码结构和命名约定来增加代码的复杂性&#xff0c;使其难以被理解和逆向工程的技术。在这篇文章中&#xff0c;我们将深入探讨JS混淆加密的一些逻辑&#xff0c;并介绍如何通过环境检测来提高代码的安全性。我们将使用案例代码演示这些概念。…

osi模型,tcp/ip模型(名字由来+各层介绍+中间设备介绍)

目录 网络协议如何分层 引入 osi模型 tcp/ip模型 引入 命名由来 介绍 物理层 数据链路层 网络层 传输层 应用层 中间设备 网络协议如何分层 引入 我们已经知道了网络协议是层状结构,接下来就来了解了解下网络协议如何分层 常见的网络协议分层模型是OSI模型 和 …

C++之结构体以及通讯录管理系统

1&#xff0c;结构体基本概念 结构体属于自定义的数据概念&#xff0c;允许用户存储不同的数据类型 2&#xff0c;结构体的定义和使用 语法&#xff1a;struct 结构体名{ 结构体成员列表}&#xff1b; 通过结构体创建变量的方式有三种&#xff1a; 1&#xff0c;struct …

python+Django+Neo4j中医药知识图谱与智能问答平台

文章目录 项目地址基础准备正式运行 项目地址 https://github.com/ZhChessOvO/ZeLanChao_KGQA 基础准备 请确保您的电脑有以下环境&#xff1a;python3&#xff0c;neo4j 在安装目录下进入cmd&#xff0c;输入指令“pip install -r requirement.txt”,安装需要的python库 打…

【LeetCode】升级打怪之路 Day 12:单调队列

今日题目&#xff1a; 239. 滑动窗口最大值 | LeetCode 今天学习了单调队列这种特殊的数据结构&#xff0c;思路很新颖&#xff0c;值得学习。 Problem&#xff1a;单调队列 【必会】 与单调栈类似&#xff0c;单调队列也是一种特殊的数据结构&#xff0c;它相比与普通的 que…

Linux入门到入土

Linxu Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX&#xff08;可移植操作系统接口&#xff09…

Onenote软件新建笔记本时报错:无法在以下位置新建笔记本

报错现象&#xff1a; 当在OneNote软件上&#xff0c;新建笔记本时&#xff1a; 然后&#xff0c;尝试重新登录微软账户&#xff0c;也不行&#xff0c;提示报错&#xff1a; 解决办法&#xff1a; 打开一个新的记事本&#xff0c;复制粘贴以下内容&#xff1a; C:\Users\Adm…

Windows上构建一个和Linux类似的Terminal

感谢大佬批评指正&#xff0c;现已更新 preview Target&#xff1a;致力打造最赏心悦目Window下的终端&#xff0c;同时能够很接近Linux的使用习惯 key word&#xff1a;windows终端美化 windows terminal windows powershell 类似Linux下的Window终端 Window也能用ll windows…