【算法】查找算法

查找算法是用于在数据集合中定位特定元素的一类算法。根据数据结构的不同和效率的要求,常见的查找算法可以分为以下几种:

1. 线性查找(Linear Search)

原理:逐个检查每个元素,直到找到目标元素或遍历完整个集合。适用于无序或有序数据。

时间复杂度:O(n)

代码示例

def linear_search(arr, target):for i in range(len(arr)):if arr[i] == target:return ireturn -1

特点:简单直接,但效率低,不适合大数据量。

2. 二分查找(Binary Search)

原理:在有序数组中,每次将查找范围减半。通过比较中间元素与目标值的大小,决定在左半部分还是右半部分继续查找。

时间复杂度:O(log n)

代码示例

def binary_search(arr, target):low, high = 0, len(arr) - 1while low <= high:mid = (low + high) // 2if arr[mid] == target:return midelif arr[mid] < target:low = mid + 1else:high = mid - 1return -1

特点:效率高,但仅适用于有序数据。常用于较大规模的有序数据集。

3. 插值查找(Interpolation Search)

原理:是一种改进的二分查找,通过估算目标的位置来决定查找范围的缩小方式,适合均匀分布的数据集。它使用一个比例公式来估计目标位置。

时间复杂度:平均 O(log log n),最坏 O(n)

代码示例

def interpolation_search(arr, target):low, high = 0, len(arr) - 1while low <= high and arr[low] <= target <= arr[high]:pos = low + ((target - arr[low]) * (high - low) // (arr[high] - arr[low]))if arr[pos] == target:return poselif arr[pos] < target:low = pos + 1else:high = pos - 1return -1

特点:比二分查找更快,但适用于分布均匀的数据集,分布不均匀时性能不佳。

4. 跳表查找(Skip List Search)

原理:在链表的基础上增加多个层次的索引,形成跳表,每层索引的跨度比上一层更大。查找时,可以先在高层索引中快速跳过一部分元素,直到接近目标元素,再进入下一层查找。

时间复杂度:O(log n)

特点:效率高,适用于动态变化的数据集,特别是在频繁插入和删除的场景中。

5. 哈希查找(Hash Search)

原理:通过哈希函数将元素映射到一个数组索引位置,再根据该位置查找目标。适合快速查找特定元素。

时间复杂度:平均 O(1)

代码示例

def hash_search(hash_table, key):index = hash(key) % len(hash_table)if hash_table[index] == key:return indexreturn -1

特点:查找速度快,但需要设计良好的哈希函数,并考虑哈希冲突的处理方法(如链表法、开放地址法)。

6. 深度优先搜索(DFS)和广度优先搜索(BFS)

适用于图或树结构中的查找,DFS 和 BFS 是用于遍历图或树节点的算法,用来查找特定节点或判断节点间的连接。

  • 深度优先搜索(DFS):沿着一个路径一直走到底,然后回溯到上一个节点,继续沿另一条路径走。
  • 广度优先搜索(BFS):按层次进行遍历,从起始节点开始,先访问一层的所有节点,再访问下一层。

时间复杂度:O(V + E)(其中 V 为顶点数,E 为边数)

代码示例(BFS)

from collections import dequedef bfs(graph, start, target):queue = deque([start])visited = set()while queue:node = queue.popleft()if node == target:return Trueif node not in visited:visited.add(node)queue.extend(graph[node])return False

特点:广泛用于路径查找、连通性检测、最短路径查找等。

7. 指数查找(Exponential Search)

原理:用于有序数组,先找到一个范围,使得目标值可能在其中,然后在该范围内使用二分查找。每次范围翻倍,直到超过目标值或数组末尾。

时间复杂度:O(log n)

代码示例

def exponential_search(arr, target):if arr[0] == target:return 0index = 1while index < len(arr) and arr[index] <= target:index *= 2return binary_search(arr[:min(index, len(arr))], target)

特点:适合无界或非常大的有序数组,通常在范围不确定的情况下使用。

8. 三分查找(Ternary Search)

原理:类似于二分查找,将数组分成三部分,根据目标值的大小选择其中一个部分继续查找。

时间复杂度:O(log3 n)

代码示例

def ternary_search(arr, target, low, high):if low > high:return -1third1 = low + (high - low) // 3third2 = high - (high - low) // 3if arr[third1] == target:return third1elif arr[third2] == target:return third2elif target < arr[third1]:return ternary_search(arr, target, low, third1 - 1)elif target > arr[third2]:return ternary_search(arr, target, third2 + 1, high)else:return ternary_search(arr, target, third1 + 1, third2 - 1)

特点:与二分查找类似,适用于有序数组,但效率通常不如二分查找。

总结

不同查找算法适合不同的数据结构和需求:

  • 线性查找:适用于无序、小规模数据。
  • 二分查找:适用于有序数组,效率高。
  • 插值查找:适用于均匀分布的有序数据。
  • 跳表查找:适合动态更新的链表结构。
  • 哈希查找:适合快速查找单个元素。
  • DFS/BFS:适用于图和树结构中的节点查找。
  • 指数查找:适合无界或非常大的有序数组。
  • 三分查找:适用于有序数组,但效率通常不如二分查找。

选择查找算法时,需要综合考虑数据规模、数据结构的特性以及查找需求。

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

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

相关文章

HTB:PermX[WriteUP]

目录 连接至HTB服务器并启动靶机 1.How many TCP ports are listening on PermX? 使用nmap对靶机TCP端口进行开放扫描 2.What is the default domain name used by the web server on the box? 使用curl访问靶机80端口 3.On what subdomain of permx.htb is there an o…

Python 项目国际化:使用 Babel 实现多语言支持

文章目录 如何使用 Babel 实现 Python 项目国际化1. 安装 Babel2. 设置项目目录结构3. 标记可翻译的文本4. 提取可翻译的文本生成文件 —— 生成pot文件4.1 有配置文件方式&#xff08;使用 babel.cfg&#xff09;4.1.1. 创建 babel.cfg 文件4.1.2. 提取翻译内容 4.2 无配置文件…

信号-2-信号捕捉

相关概念&#xff1a;递达 未决 / 阻塞 忽略 阻塞 vs 忽略 阻塞&#xff1a; 如果指定信号信号被阻塞&#xff0c; block期间该信号不能被递达&#xff0c;一直在pending表中。知道block被撤销后&#xff0c; 该信号才能递达&#xff0c;递达后对应pending位置置零。 忽…

正则表达式1 re.match惰性匹配详解案例

点个关注 re.match() re.match() 函数尝试从字符串的开头开始匹配一个模式&#xff0c;如果匹配成功&#xff0c;返回一个匹配成功的对象&#xff0c;否则返回None。大小写区分&#xff0c;内容匹配不到后面的,只能匹配一个&#xff0c;不能有空格&#xff08;开头匹配&#…

如何针对云计算安全进行等保测评?

等级保护作为我国网络安全法明确的重要制度&#xff0c;已在我国信息系统安全保驾护航中发挥着重要作用。目前&#xff0c;等级保护已经进入了2.0时代&#xff0c;“云、大、物、移、工控”纳入等保监管。 当前&#xff0c;按照传统等级保护技术要求实施的安全策略已经不能适应…

软考:性能测试的几个方面

性能测试的指标&#xff1a; 响应时间&#xff0c;吞吐量&#xff0c;并发用户数&#xff0c;资源利用率等 四个方面&#xff1a; 1、发现缺陷 2、性能调优 3、评估系统能力&#xff0c;不仅需要&#xff0c;还需要。 4、验证稳定性和可靠性

Vue(JavaScript)读取csv表格并求某一列之和(大浮点数处理: decimal.js)

文章目录 想要读这个表格&#xff0c;并且求第二列所有价格的和方法一&#xff1a;通过添加文件输入元素上传csv完整&#xff08;正确&#xff09;代码之前的错误部分因为价格是小数&#xff0c;所以下面的代码出错。如果把parseFloat改成parseInt&#xff0c;那么求和没有意义…

搭建兰空图床并配合PicGo实现批量上传

文章目录 服务器安装docker安装数据库部署兰空图床兰空图床配置邮箱验证配合PicGo实现批量上传 最近想试试自己搭建图床&#xff0c;虽然免费的又拍云够用了&#xff0c;但对象存储和图床还是有区别的&#xff0c;用起来有些复杂&#xff0c;所以打算试试兰空图床 服务器 想搭建…

如何对数据库的表字段加密解密处理?

对于表格数据的加密处理&#xff0c;通常涉及到对数据库中存储的数据进行加密&#xff0c;以保护敏感信息。 Java示例&#xff08;使用AES算法加密数据库表数据&#xff09; 首先&#xff0c;你需要一个数据库连接&#xff0c;这里假设你使用的是JDBC连接MySQL数据库。以下是…

LLM训练”中的“分布式训练并行技术;分布式训练并行技术

目录 “LLM训练”中的“分布式训练并行技术” 分布式训练并行技术 数据并行 流水线并行:按阶段(stage)进行切分 张量并行 序列并行 多维混合并行 自动并行 MOE并行 重要的分布式AI框架 “LLM训练”中的“分布式训练并行技术” 随着深度学习技术的不断发展,特别是…

TS学习笔记

一、TS运行环境搭建 1、安装 安装命令 npm i -g typescript 第一步&#xff1a;新建index.html和demo.ts 第二步&#xff1a;在index.html引入demo.ts文件 第三步&#xff1a;运行TS的命令 tsc demo.ts 注意&#xff1a;运行命令后&#xff0c;会将ts文件转换成js文件 …

ubuntu 22.04 server 安装 和 初始化 LTS

ubuntu 22.04 server 安装 和 初始化 下载地址 https://releases.ubuntu.com/jammy/ 使用的镜像是 ubuntu-22.04.5-live-server-amd64.iso usb 启动盘制作工具 https://rufus.ie/zh/ rufus-4.6p.exe 需要主板 支持 UEFI 启动 Ubuntu22.04.4-server安装 流程 https://b…

Python接口自动化测试实战

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 接口自动化测试是指通过编写程序来模拟用户的行为&#xff0c;对接口进行自动化测试。Python是一种流行的编程语言&#xff0c;它在接口自动化测试中得到了广泛…

day01 - web开发简介

本课程涉及到的技术&#xff1a; Vue ElementUI/Html Js SpringBoot–Spring SpringMvc MyBatis(Plus) SSM Axios 学习路径&#xff1a; 前端主要&#xff1a; Html5css3JavaScript(JQuery)–>Vue(Node.js也可以学习一 下&#xff0c;服务端js)ElementUi(uni-app) 后端主要…

qt QMessageBox详解

1、概述 QMessageBox是Qt库中的一个类&#xff0c;它用于在图形用户界面&#xff08;GUI&#xff09;程序中显示消息框。消息框是一种用于向用户显示信息、警告、错误或询问用户确认的对话框。QMessageBox可以显示文本、图标和按钮&#xff0c;并允许自定义按钮的文本和功能。…

简易版 python调用cuda方法

目标: 手写一些cuda库, 使用python调用这些库 (Linux) 步骤一: 在linux上安装pybind11 方法1: sudo apt-get install python3-pybind11 方法2: git clone https://github.com/pybind/pybind11.git, 如果将其放在项目目录下的话可以不编译 步骤二: 编写CUDA代码 示例: gpu_l…

51单片机学习心得2(基于STC89C52):串口通信(UART)

串口通信&#xff08;UART&#xff09; 电平标准 &#xff08;注意&#xff1a;单片机中常使用TTL电平&#xff09; 上图中第一种与第二种电平传输信号有效距离只有十几米&#xff0c;距离超出后会传输数据错误&#xff1b;但是第三种电平传输的有效距离可达上千米。 常用通信…

gitlab-runner中搭建nvm、nrm以及优化maven打包

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 gitlab-runner中搭建nvm、nrm以及优化maven打包 git、gitlab-runner如何以gitlab-runner执行nvm、…

一文读懂:AIOps 从自动化运维到智能化运维

今天跟大家聊一聊AIOps&#xff08;人工智能运维&#xff09; 为了应对企业面临着日益复杂的运营挑战&#xff0c;AIOps&#xff08;人工智能运维&#xff09;作为一种创新的方法应运而生&#xff0c;结合了人工智能和机器学习技术&#xff0c;来提升IT运营的效率和性能。 这…

Java反射

动态代理 java.lang.reflect.Proxy:提供了为对象产生代理的方法&#xff1a; public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) loader&#xff1a;指定用哪个类加载器&#xff0c;去加载生成的代理类。interfa…