二分查找 - 数据结构和算法教程

news2024/9/29 7:26:04

二分查找被定义为在排序数组中使用的一种搜索算法,它通过重复将搜索间隔分成两半来实现。二分查找的思想是利用数组被排序的信息,将时间复杂度降低到O(log N)。

在这里插入图片描述

在数据结构中应用二分查找的条件

  • 数据结构必须排序。
  • 访问数据结构的任何元素都需要恒定的时间。

二分查找算法

在该算法中,

  • 通过查找中间索引“mid”将搜索空间分成两半。
    在这里插入图片描述
  • 将搜索空间的中间元素与键进行比较。
  • 如果在中间元素处找到键,则终止该过程。
  • 如果在中间的元素处没有找到键,请选择将哪一半用作下一个搜索空间。
    • 如果关键字小于中间的元素,则左侧用于下一次搜索。
    • 如果关键字大于中间的元素,则右侧用于下一次搜索。
  • 这个过程一直持续到找到关键字或耗尽总搜索空间。

二分查找是如何工作的?

考虑一个数组arr[] = {2,5,8,12,16,23,38,56,72,91},目标= 23。

第一步:计算mid并将mid元素与目标key进行比较。如果键小于mid元素,则向左移动,如果键大于mid元素,则向右移动搜索空间。

  • key(23)大于当前的中间元素(16)。搜索空间向右移动。
    在这里插入图片描述

  • key小于当前的中位56。搜索空间向左移动。
    在这里插入图片描述

第二步:如果键与mid元素的值匹配,则找到该元素并停止搜索。
在这里插入图片描述

如何实现二分查找?

二进制搜索算法可以通过以下两种方式实现

  • 迭代二分查找算法
  • 递归二分搜索算法

下面给出的是这些方法的伪代码。

1.迭代二分查找算法:

在这里,我们使用一个while循环来继续比较键并将搜索空间分成两半的过程。

迭代二分查找python实现:


# It returns location of x in given array arr
def binarySearch(arr, l, r, x):

	while l <= r:

		mid = l + (r - l) // 2

		# Check if x is present at mid
		if arr[mid] == x:
			return mid

		# If x is greater, ignore left half
		elif arr[mid] < x:
			l = mid + 1

		# If x is smaller, ignore right half
		else:
			r = mid - 1

	# If we reach here, then the element
	# was not present
	return -1


# Driver Code
if __name__ == '__main__':
	arr = [2, 3, 4, 10, 40]
	x = 10

	# Function call
	result = binarySearch(arr, 0, len(arr)-1, x)
	if result != -1:
		print("Element is present at index", result)
	else:
		print("Element is not present in array")

输出:

Element is present at index 3

时间复杂度:O(log N)
空间复杂度:O(1)

2.递归二分查找算法:

创建一个递归函数,并将搜索空间的中点与键进行比较。并根据结果返回找到键的索引或调用下一个搜索空间的递归函数。

递归二分查找python实现:

# Returns index of x in arr if present, else -1
def binarySearch(arr, l, r, x):

	# Check base case
	if r >= l:

		mid = l + (r - l) // 2

		# If element is present at the middle itself
		if arr[mid] == x:
			return mid

		# If element is smaller than mid, then it
		# can only be present in left subarray
		elif arr[mid] > x:
			return binarySearch(arr, l, mid-1, x)

		# Else the element can only be present
		# in right subarray
		else:
			return binarySearch(arr, mid + 1, r, x)

	# Element is not present in the array
	else:
		return -1


# Driver Code
if __name__ == '__main__':
	arr = [2, 3, 4, 10, 40]
	x = 10
	
	# Function call
	result = binarySearch(arr, 0, len(arr)-1, x)
	
	if result != -1:
		print("Element is present at index", result)
	else:
		print("Element is not present in array")

输出:

Element is present at index 3

二分查找的复杂度分析

时间复杂度:
最佳情况:O(1)
平均情况:O(log N)
最坏情况:O(log N)
空间复杂度:O(1),如果考虑递归调用栈,那么空间复杂度为O(logN)。

二分查找的优点

  • 二分查找比线性搜索更快,特别是对于大型数组。
  • 比具有类似时间复杂度的其他搜索算法(例如插值搜索或指数搜索)更有效。
  • 二分查找非常适合搜索存储在外部存储器中的大型数据集,例如硬盘驱动器或云中。

二分查找的缺点

  • 数组应该排序。
  • 二分查找要求被搜索的数据结构存储在连续的存储器位置中。
  • 二分查找要求数组的元素是可比较的,这意味着它们必须能够被排序。

二分查找的应用

  • 二分查找可以用作机器学习中使用的更复杂算法的构建块,例如用于训练神经网络或找到模型的最佳超参数的算法。
  • 它可以用于计算机图形学中的搜索,例如光线跟踪或纹理映射算法。
  • 它可以用来搜索数据库。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac为什么读取不了NTFS格式硬盘,Tuxera NTFS for Mac 2022 读写ntfs移动硬盘插件

使用 Mac 的巨大痛点之一&#xff1a;移动硬盘只能打开文件&#xff0c;但是无法写入新的资料。有人说格式化硬盘&#xff0c;改成苹果的 macOS扩展格式&#xff0c;但是原先硬盘的数据要转移&#xff0c;而且拿到 Windows 系统里无法被识别。 有人说格式化硬盘&#xff0c;改…

关于nginx,正向代理和反向代理是什么意思

为什么要使用nginx 很多公司会用到nginx做代理服务器&#xff0c;为什么用nginx&#xff0c;tomcat服务器不行吗&#xff1f; tomcat缺点&#xff1a;并发量小&#xff0c;用户使用的少 nginx&#xff1a;高并发&#xff0c;高性能&#xff0c;cpu、内存等资源消耗却非常低&…

在 Navicat Premium 中管理 MySQL 用户 | 第 4 部分:权限管理员工具

第 4 部分&#xff1a;权限管理员工具 在本系列中&#xff0c;我们一直在探索如何使用 Navicat 的旗舰产品 Navicat Premium 执行常见的用户管理任务。在上一篇文章中&#xff0c;我们研究了新用户对象选项卡的“服务器权限”、“权限”和“SQL预览”选项卡。 在上一篇文章中…

前程无忧guid、acw_sc__v2

文章目录 声明目标网站acw_sc__v2分析python调用测试话外拓展-风控浅析往期逆向文章推荐 声明 本文章中所有内容仅供学习交流&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请私信我立即删除&#x…

【测试】Selenium操作Cookie

1.操作Cookie 操作Cookie无非就是读取和删除Cookie&#xff0c;下面这些是主要方法 from selenium.webdriver import Chrome, ChromeOptions from selenium.webdriver.chrome.service import Serviceoptions ChromeOptions() options.add_argument("--ignore-certifica…

07-source-map

source-map是从已转换的代码&#xff0c;映射到原始的源文件。使浏览器可以重构原始源并在调试器中显示重建的原始源。 根据源文件&#xff0c;生成source-map文件&#xff0c;webpack在打包时&#xff0c;可以通过配置生成source-map&#xff1b; 在转换后的代码&#xff0c;…

Springboot整合mybatisplus实战

Springboot整合mybatisplus&#xff0c;纯后端&#xff0c;验证结果是通过postman调用的&#xff0c;记录一下 1、建表语句以及初始化数据脚本 CREATE TABLE tbl_book (id int NOT NULL AUTO_INCREMENT,type varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT…

Django之模板层

一、模板简介 在刚刚介绍完的视图层中我们提到&#xff0c;浏览器发送的请求信息会转发给视图进行处理&#xff0c;而视图在经过一系列处理后必须要有返回信息给浏览器。如果我们要返回html标签、css等数据给浏览器进行渲染&#xff0c;我们可以在视图中这么做 from django.s…

Git进阶系列 | 3. 基于Pull Request实现更好的协作

Git是最流行的代码版本控制系统&#xff0c;这一系列文章介绍了一些Git的高阶使用方式&#xff0c;从而帮助我们可以更好的利用Git的能力。本系列一共8篇文章&#xff0c;这是第3篇。原文&#xff1a;Better Collaboration With Pull Requests[1] 本文是“Git进阶系列”的第三篇…

Keil 重定向 fputc 函数 以及 printf 函数的代码尺寸测试

本文的开发环境为 Keil Cortex-M3 内核处理器。 重定向 fputc 函数方法 如果想使用库函数 printf &#xff0c;必须要将 fputc 重定向到自己的串口上。 术语 重定向 可以理解为用户重写 fputc 函数&#xff0c;在重写的函数体内调用自己硬件的串口发送函数。 在 Keil 环境中…

Android Binder通信原理(二):servicemanager启动

源码基于&#xff1a;Android R 0. 前言 下图是android 8.0 之前binder 的软件框架&#xff0c;依赖的驱动设备是/dev/binder&#xff0c;binder机制的四要素分别是client、server、servicemanager和binder驱动。 对于android 8.0后的binder 和vndbinder依然同这个框架&#…

【Python版】手把手带你如何进行Mock测试

什么是mock&#xff1f; mock测试是以可控的方式模拟真实的对象行为。程序员通常创造模拟对象来测试对象本身该具备的行为&#xff0c;很类似汽车设计者使用碰撞测试假人来模拟车辆碰撞中人的动态行为 为什么要使用Mock&#xff1f; 之所以使用mock测试&#xff0c;是因为真…

js+html+css 封装一个弹窗组件

HTML中通过一个按钮触发显示弹窗的函数showPopup()&#xff0c;弹窗的内容包含在一个div元素中&#xff0c;初始设置为隐藏状态。 CSS中定义了弹窗的样式&#xff0c;包括背景、位置、边框等。 JavaScript中定义了两个函数showPopup()和hidePopup()&#xff0c;分别用于显示和隐…

CORS原理及解决办法

浏览器的同源策略阻止读取来自不同来源的资源。这种机制阻止恶意站点读取另一个站点的数据&#xff0c;但它也阻止合法使用。 一般情况下&#xff0c;我们可以通过两种方式解决浏览器的同源策略&#xff0c;JSONP和CORS,CORS解决方案更为通用&#xff08;推荐&#xff09;。 …

算法程序设计 之 胖男孩问题(7/8)

一、题目分析 问题描述 麦克结婚后&#xff0c;在上个月他胖了70磅。因为手指上的脂肪过多&#xff0c;使他连给他最亲密的朋友斯拉夫克写一个电子邮件都很困难。 每晚麦克都详细地描述那一天他所吃的所有东西&#xff0c;但有时当他只想按一次某键时往往会按了不止一次&…

java 读取图片中的文字

Maven依赖导入Tess4j <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j --><dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>4.5.4</version></de…

基于SpringBoot的二手书交易系统的设计与实现(源码、数据库、文档)

作为新兴事物&#xff0c;校园电子商务是&#xff0c;首先是指在校园范围内&#xff0c;其技术手段是校园网&#xff0c;而服务对象是全部师生。主要经营形式为学生自主经营&#xff0c;能够满足多群体生活学习需求&#xff0c;同时具备范围小&#xff0c;安全性高&#xff0c;…

《Web应用技术》期末复习(END)

说明&#xff1a;不知道是哪位兄台在群里说了一句&#xff0c;整的我压力山大。这是我个人的期末复习梳理&#xff0c;自己使用并且提供给几位有需要的朋友使用&#xff0c;并不确定期末考试考不考这些。请大家视情况查看和使用&#xff0c;如果有错误&#xff0c;也欢迎大家找…

opencv如何使用GPU的三种方法

我在工作实验涉及到图像和视频处理时&#xff0c;通常使用opencv提供的库来做处理&#xff0c;虽然OpenCV是一个广泛使用的库&#xff0c;它提供了丰富的功能和工具。然而&#xff0c;有时候在处理大量图片或视频时&#xff0c;我们可能会面临速度受限的问题。 opencv执行图像…

SpringMvc拦截器入门

文章目录 前言五、拦截器入门1.拦截器简介2.拦截器入门案例3.拦截器参数4. 拦截器链配置 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。当然&#xff0c;如果能帮到一些萌新进行新技术的学习那也是极好的。作者…