说说你对二分查找的理解?如何实现?应用场景?

在这里插入图片描述

一、是什么

在计算机科学中,二分查找算法,也称折半搜索算法,是一种在有序数组中查找某一特定元素的搜索算法

想要应用二分查找法,则这一堆数应有如下特性:

  • 存储在数组中
  • 有序排序

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束

如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较

如果在某一步骤数组为空,则代表找不到

这种搜索算法每一次比较都使搜索范围缩小一半

如下图所示:

在这里插入图片描述
相比普通的顺序查找,除了数据量很少的情况下,二分查找会比顺序查找更快,区别如下所示:
在这里插入图片描述

二、如何实现

基于二分查找的实现,如果数据是有序的,并且不存在重复项,实现代码如下:

function BinarySearch(arr, target) {
    if (arr.length <= 1) return -1
    // 低位下标
    let lowIndex = 0
    // 高位下标
    let highIndex = arr.length - 1

    while (lowIndex <= highIndex) {
        // 中间下标
        const midIndex = Math.floor((lowIndex + highIndex) / 2)
        if (target < arr[midIndex]) {
            highIndex = midIndex - 1
        } else if (target > arr[midIndex]) {
            lowIndex = midIndex + 1
        } else {
            // target === arr[midIndex]
            return midIndex
        }
    }
    return -1
}

如果数组中存在重复项,而我们需要找出第一个制定的值,实现则如下:

function BinarySearchFirst(arr, target) {
    if (arr.length <= 1) return -1
    // 低位下标
    let lowIndex = 0
    // 高位下标
    let highIndex = arr.length - 1

    while (lowIndex <= highIndex) {
        // 中间下标
        const midIndex = Math.floor((lowIndex + highIndex) / 2)
        if (target < arr[midIndex]) {
            highIndex = midIndex - 1
        } else if (target > arr[midIndex]) {
            lowIndex = midIndex + 1
        } else {
            // 当 target 与 arr[midIndex] 相等的时候,如果 midIndex 为0或者前一个数比 target 小那么就找到了第一个等于给定值的元素,直接返回
            if (midIndex === 0 || arr[midIndex - 1] < target) return midIndex
            // 否则高位下标为中间下标减1,继续查找
            highIndex = midIndex - 1
        }
    }
    return -1
}

实际上,除了有序的数组可以使用,还有一种特殊的数组可以应用,那就是轮转后的有序数组

有序数组即一个有序数字以某一个数为轴,将其之前的所有数都轮转到数组的末尾所得

例如,[4, 5, 6, 7, 0, 1, 2]就是一个轮转后的有序数组

该数组的特性是存在一个分界点用来分界两个有序数组,如下:
在这里插入图片描述
分界点有如下特性:

  • 分界点元素 >= 第一个元素
  • 分界点元素 < 第一个元素

代码实现如下:

function search (nums, target) {
  // 如果为空或者是空数组的情况
  if (nums == null || !nums.length) {
    return -1;
  }
  // 搜索区间是前闭后闭
  let begin = 0,
    end = nums.length - 1;
  while (begin <= end) {
    // 下面这样写是考虑大数情况下避免溢出
    let mid = begin + ((end - begin) >> 1);
    if (nums[mid] == target) {
      return mid;
    }
    // 如果左边是有序的
    if (nums[begin] <= nums[mid]) {
      //同时target在[ nums[begin],nums[mid] ]中,那么就在这段有序区间查找
      if (nums[begin] <= target && target <= nums[mid]) {
        end = mid - 1;
      } else {
        //否则去反方向查找
        begin = mid + 1;
      }
      //如果右侧是有序的
    } else {
      //同时target在[ nums[mid],nums[end] ]中,那么就在这段有序区间查找
      if (nums[mid] <= target && target <= nums[end]) {
        begin = mid + 1;
      } else {
        end = mid - 1;
      }
    }
  }
  return -1;
};

对比普通的二分查找法,为了确定目标数会落在二分后的哪个部分,我们需要更多的判定条件

三、应用场景

二分查找法的O(logn)让它成为十分高效的算法。不过它的缺陷却也是比较明显,就在它的限定之上:

  • 有序:我们很难保证我们的数组都是有序的
  • 数组:数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n),并且数组的存储是需要连续的内存空间,不适合大数据的情况

关于二分查找的应用场景,主要如下:

  • 不适合数据量太小的数列;数列太小,直接顺序遍历说不定更快,也更简单
  • 每次元素与元素的比较是比较耗时的,这个比较操作耗时占整个遍历算法时间的大部分,那么使用二分查找就能有效减少元素比较的次数
  • 不适合数据量太大的数列,二分查找作用的数据结构是顺序表,也就是数组,数组是需要连续的内存空间的,系统并不一定有这么大的连续内存空间可以使用

参考文献

  • https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E5%B0%8B%E6%BC%94%E7%AE%97%E6%B3%95#javascript_%E7%89%88%E6%9C%AC
  • https://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

招商画册不会制作?这个教程收藏好

在制作招商画册过程中可能对于一些小型企业或刚刚起步的企业来说&#xff0c;招商画册的制作也不是一个难以克服的难题。本文将为您提供一些制作招商画册的技巧和建议。在制作招商画册前肯定是需要选择一款合适的在线制作工具&#xff0c;如FLBOOK 这个平台本就有海量的模板和设…

vue快速入门(四十四)自定义组件

注释很详细&#xff0c;直接上代码 上一篇 新增内容 全局注册自定义组件并应用局部注册自定义组件并应用 此篇使用了axios模块没有安装导入的先看这一篇 axios模块下载与导入 源码 main.js import Vue from vue import App from ./App.vue//全局引入axios // 引入axios impor…

超市火灾烟雾蔓延及人员疏散的matlab模拟仿真,带GUI界面

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 出口在人员的视野范围内时&#xff0c;该元胞选择朝向引导点的方向运动。出口不在人员的视野范围内时&#xff0c;作随机运动&#xff0c;8个方向的运动概率相等。…

网工交换基础——Qinq技术

一、Qinq的概述 QinQ&#xff08;802.1Q-in-802.1Q&#xff09;&#xff0c;也叫做VLAN Stacking或Double VLAN&#xff0c;由IEEE 802.1ad标准定义&#xff0c;是一项扩展VLAN空间的技术&#xff0c;通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩展VLAN空间的目…

Linux驱动开发——(六)按键中断实验

目录 一、简介 二、修改设备树 2.1 添加pinctrl节点 2.2 添加KEY设备节点 2.3 检查是否被其他外设使用 三、代码 3.1 驱动代码 3.2 测试代码 3.3 平台测试 一、简介 以I.MX6U-MINI为例&#xff0c;实现KEY0按下后&#xff0c;设备识别到并将数据发送到平台。 二、修…

40-数组 _ 数组越界

40-1 数组的下标是有范围限制的 数组的下标规定是从0开始的&#xff0c;如果数组有n个元素&#xff0c;最后一个元素的下标就是n-1。所以数组的下标如果小于0&#xff0c;或者大于n-1&#xff0c;就是数组越界访问了&#xff0c;超出了数组合法空间的访问。 C语言本身不做数组…

VUE2版本的仿微信通讯录侧滑列表

<template><!-- Vue模板部分 --><div><div v-for"(group, index) in groupedArray" :key"index" ref"indexcatch"><h2>{{ letter[index] }}</h2><ul><li v-for"item in group" :key&quo…

python基础--文件操作

目标 文件操作的作用文件的基本操作 打开读写关闭 文件备份文件和文件夹的操作 一. 文件操作的作用 思考&#xff1a;什么是文件&#xff1f; 思考&#xff1a;文件操作包含什么&#xff1f; 答&#xff1a;打开、关闭、读、写、复制… 思考&#xff1a;文件操作的的作用…

聚类分析字符串数组

聚类分析字符串数组 对多个字符串进行聚类分析旨在根据它们之间的相似度将这些字符串划分成若干个类别&#xff0c;使得同一类别内的字符串彼此相似度高&#xff0c;而不同类别间的字符串相似度低 小结 数据要清洗。清洗的足够准确&#xff0c;可能不需要用聚类分析了数据要…

45. 【Android教程】内容提供者 - Content Provider

本节学习最后一个 Android 组件——内容提供者。顾名思义&#xff0c;它可以用来给其他的 App 提供各种内容&#xff0c;比如 Android 自带的短信、联系人、日历等等都是一个普通的 App&#xff0c;当你需要这些内容的时候&#xff0c;就可以向它们的 Content Provider 发起请求…

C/C++ 入门(7)vector类(STL)

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、标准库中的vector 1、了解 2、vector常用接口 二、vector的实现 1、框架 2、构造、析构函数 3、操作函数 三 、问题 1、由于赋值而引起的浅拷贝 2、因为类没…

【linux】多路径|Multipath I/O 技术

目录 简略 详细 什么是多路径? Multipath安装与使用 安装 使用 Linux下multipath软件介绍 附录 配置文件说明 其他解 简略 略 详细 什么是多路径? 普通的电脑主机都是一个硬盘挂接到一个总线上&#xff0c;这里是一对一的关系。 而到了分布式环境&#xff0c;主机和存储网络连…

普冉PY32F071单片机简单介绍,QFN64 48封装,支持 8 * 36 / 4 * 40 LCD

PY32F071单片机是一款基于32 位 ARM Cortex - M0内核的微控制器&#xff0c;由普冉半导体推出。PY32F071可广泛应用于各种嵌入式系统中&#xff0c;包括消费类电子产品、工业自动化、医疗设备等领域。PY32F071系列单片机具有低功耗、高性能和丰富的外设接口等特点&#xff0c;适…

生物制药企业在选择文件摆渡平台时,最应该关注哪些功能?

生物制药是以数据为核心生产力的企业&#xff0c;数据的重要性体现在药物研发、生产优化、销售和市场营销、决策支持以及合规要求等多个方面。有效地管理和利用数据&#xff0c;对于提升企业的竞争力、降低风险、提高产品质量和满足市场需求具有重要意义。 为保护数据安全&…

KEITHLEY(吉时利)2440源测量单位(SMU)数字源表

KEITHLEY(吉时利&#xff09;2440源测量单位&#xff08;SMU)数字源表 主要特性 50W 时性能高达 5A / 40V0.012&#xff05; 基本测量精度&#xff0c;具有 6 位分辨率10pA / 100nV 测量分辨率与 KickStart 软件结合使用美国2440吉时利keithley数字源表特点 2400系列提供宽动…

亚信安慧AntDB:高效与稳定

亚信安慧AntDB正致力于验证数据库软硬件全自主可控的可行性&#xff0c;并将其应用于运营商核心的交易场景&#xff0c;以替代国外商业解决方案。为了实现这一目标&#xff0c;亚信安慧AntDB的研发团队不断进行技术创新和实践探索。 该数据库以自主研发的技术为基础&#xff0…

C语言 流程图与伪代码 缩减

本文 我们来说说流程图 伪代码和代码缩进 这些可以让我们在后面书写复杂逻辑时 不会感到 繁琐或逻辑混乱 流程图(Flowchart) 是用以算法、工作流或流程的一种框图表示&#xff0c;它以不同类型的框代表不同种类的步骤&#xff0c;每两个步骤之间则以箭头连接。 流程图是程序…

《飞吧龙骑士》新版本“龙神祭”盛大开启,引领骑士团战

热游圈消息&#xff1a;五一假期临近&#xff0c;备受瞩目的手游《飞吧龙骑士》迎来重大更新——“龙神祭”新版本正式开启。在此次更新中&#xff0c;首个蓄力炮UR龙——绮舞的巫女千代烬惊艳登场&#xff0c;为玩家们带来前所未有的燃情体验。同时&#xff0c;全新骑士团战玩…

当你看到一份更心仪的工作时,先冷静冷静,看看这篇文章

01 无法构建自己的城堡&#xff1f;那就挖一条护城河 人活一辈子&#xff0c;在职业生涯领域&#xff0c;你总得要搭建一座属于自己的城堡&#xff0c;否则拼死拼活&#xff0c;到最后你拿到一点蝇头小利&#xff0c;为别人做嫁衣。而当别人的梦想进行曲不需要你合奏或者伴奏时…

从现在开始:让AI写代码,你只负责敲tab键

如果你是一名程序员&#xff0c;你一定有过这样的经历&#xff1a;在编写代码的时候&#xff0c;突然遇到了一个棘手的问题&#xff0c;需要花费大量的时间去查找资料、尝试不同的解决方案&#xff0c;甚至有时候还需要去问同事或者在网上寻求帮助。这样的情况不仅会浪费你的时…
最新文章