数据结构:数组:线性查找(Linear Search)

目录

什么是线性查找?

时间复杂度分析

🧠 线性查找的优化

方法一:Move to Front(哨兵) 

方法二:Transportation(向前交换一步) 


什么是线性查找?

我们先问:你想做什么?

你现在有一个数组:

A = [3, 5, 9, 7, 2, 6]

你想查找一个值,比如 7,问:

❓ 它在数组中的哪个位置?

从前往后,一个一个看!

也就是说:

  • 比较 A[0] 是不是 7?不是

  • 比较 A[1] 是不是 7?不是

  • 比较 A[2] 是不是 7?不是

  • 比较 A[3] 是不是 7?✅ 是!

找到它的位置啦,返回 3!

这就是——线性查找(Linear Search) 

从数组的 第一个元素开始,一个一个往后找,直到找到目标值,或者整个数组都遍历完。 

  • 数组 A,长度 n

  • 要查找的目标值 key

查找过程:

  • 遍历数组中每一个元素

  • 如果某个元素等于 key,返回它的索引

  • 如果一直没找到,说明它不存在,返回 -1

那么如果没找到怎么办?

你需要返回一个“不可能的合法索引”来表示失败。

❓为什么选 -1?

  • 数组索引是从 0 开始的,最小索引是 0

  • 所以 -1 永远不是合法索引 → 非常适合表示 “查找失败”

int linearSearch(int A[], int n, int key) {for (int i = 0; i < n; i++) {if (A[i] == key) {return i;  // 找到了,返回位置}}return -1;  // 没找到
}

时间复杂度分析

情况比较次数时间复杂度
最好情况(第一个就找到)1 次O(1)
最坏情况(最后一个找到或找不到)n 次O(n)
平均情况≈ n/2 次O(n)

结论:🕒 时间复杂度是 O(n)

因为你可能需要检查数组中每一个元素。 

空间复杂度分析

你只是访问数组,没有开新空间 → ✅ 空间复杂度是:O(1)(常数)

线性查找的适用场景

适合情况不适合情况
 数组无序 数组有序(用二分更快)
 数据量小 数据量大
 查找频率低 查找频率高

🧠 线性查找的优化

我们从最根本的问题问起:我们为什么需要优化线性查找? 

for (int i = 0; i < n; i++)if (A[i] == key)return i;

原始线性查找算法的时间复杂度是 O(n),也就是说:

  • 如果数组很长,查找一个元素可能非常慢;

  • 每次都要从头开始;

  • 哪怕你经常查找的是第 98 个元素,也要前面白比对 97 次。

Step 1:识别性能瓶颈

我们思考:

线性查找性能差的根源是什么?

答:不知道哪些值常用,每次都必须从头查到尾。

Step 2:寻找提升策略(性能原理)

我们继续问:

有什么办法能让「经常被查找的值」查得更快?

思路:

  • 如果某些值经常被查找,我们能不能让它们靠前一点?

  • 这样,下次查找时更容易「提前命中」

这就是“利用访问频率的非均匀性(局部性)” —— 稀疏的优化策略

✅ Step 3:能不能改变数组顺序?

思考:

原来的数组是按什么顺序排的?

线性查找不要求有序 →  我们可以调整顺序!

也就是说,我们可以「根据使用情况」来调整数组布局,让常查元素靠前

✅ Step 4:目标明确:让“热点元素”靠前

现在我们有了优化目标:

每次找到目标之后,想办法把它往前移!

这样下次更容易早找到。

 ✅ Step 5:两种“往前移”的方式自然浮现

方法一:Move to Front(哨兵) 

📌 思考方式:

既然你这么重要,我就把你提到最前面,以后第一个找你!

操作步骤:

  1. 找到元素 A[i]

  2. 将其值保存为 temp

  3. 从 i 往前,把 A[j-1] 移动到 A[j]

  4. 把 temp 放在 A[0]

为什么合理?

  • 查过一次,就代表可能未来还会查 → 越早命中越好

  • 不考虑“稳定性”,直接调整顺序 → 速度最优

原地移动(图示)

原数组:

[3][5][9][7][2]    ← 要查找 7↑

找到 A[3] == 7
→ 把 7 放到 A[0]
→ 其他人向后退一格:

结果:

[7][3][5][9][2]

优化后平均查找时间会降低,因为如果 7 是高频元素,那么:

  • 查找第一次:代价 O(n)

  • 查找第二次:它已经在最前面了!→ O(1)


方法二:Transportation(向前交换一步) 

📌 思考方式:

如果你被查到了,我让你「进一格」,但不会一下子到最前

操作步骤:

  1. 找到元素 A[i]

  2. 与 A[i−1] 交换

为什么要这么温和?

  • 如果一查就放最前,有可能误判“偶然热点”

  • Transpose 是「缓慢上升」→ 更公平,更“稳定”

原地交换(图示)

原数组:

[3][5][9][7][2]↑

找到 A[3] = 7
→ 与 A[2] = 9 交换

结果:

[3][5][7][9][2]

 下次再查到,就会再往前。


✅ Step 6:代码实现

Move to Front:

int linearSearchMoveToFront(int A[], int n, int key) {for (int i = 0; i < n; i++) {if (A[i] == key) {// 将 A[i] 移动到前面int temp = A[i];for (int j = i; j > 0; j--) {A[j] = A[j - 1];}A[0] = temp;return 0;  // 返回新位置}}return -1;
}

Transportation: 

int linearSearchTranspose(int A[], int n, int key) {for (int i = 0; i < n; i++) {if (A[i] == key) {if (i > 0) {swap(A[i], A[i - 1]);return i - 1;}return i;}}return -1;
}

这就是从“行为本质”出发的两种优化策略!

总结:

从第一性原理出发,线性查找的本质缺陷是“对所有元素一视同仁”。

而优化的核心思想是:

“把重要的人提前排队”,不让高频元素总排在后面白等。

Move-to-front 是“VIP 通道”,Transpose 是“按表现升位”。 

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

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

相关文章

石子入水波纹效果:UV扰动着色器实现

利用UV坐标扰动来模拟水面是一种常见且有效的技术手段,上述效果主要通过对水面纹理的UV坐标进行动态偏移或扰动,从而模拟水波的流动和波纹效果。资源下载具体实现和原理如下: 基本思路:通过对水面纹理的UV坐标加上时间相关的扰动函数(如正弦波、余弦波、噪声函数等),使纹…

Java Lambda 类型推断详解:filter() 方法与 Predicate<? super T>

一、问题核心解析1. 代码示例分析List<String> strings Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered strings.stream().filter(string -> !str…

XSS:xss.haozi.me靶场练习

超链接:alert(1) 知识点: html <&#xff01;--被注释的内容--> <&#xff01;--被注释的内容!--> php /*被注释的内容*/ //被注释的内容 javascript /*被注释的内容*/ //被注释的内容 MySQL …

ubuntu 20.04 安装中文输入法 (sougou pin yin)

安装搜狗输入法包 参照官方指南完成 如果提示没有找到相关依赖&#xff0c;添加一下源&#xff1a; sudo add-apt-repository universe sudo apt update重启。

(DETR)End-to-End Object Detection with Transformers论文精读(逐段解析)

(DETR)End-to-End Object Detection with Transformers论文精读&#xff08;逐段解析&#xff09; 论文地址&#xff1a;https://arxiv.org/abs/2005.12872 CVPR 2020 Facebook AI 发布 Abstract. We present a new method that views object detection as a direct set pred…

[linux][shell]通过分析 Nginx 的访问日志,检测异常 IP 地址并使用iptables 将其封禁

这段脚本的作用是通过分析 Nginx 的访问日志&#xff0c;检测异常的 IP 地址&#xff0c;并使用 iptables 封禁这些 IP。#!/bin/bash# 配置变量 LOG_FILE"/usr/local/nginx/logs/access.log" THRESHOLD10 DROP_LOG_FILE"/tmp/drop_ip.log" DATE$(date &quo…

stm32cube ide如何将工具链替换成arm-none-eabi-gcc

在 STM32Cube IDE 中替换工具链为GNU Arm Embedded Toolchain (arm-none-eabi-gcc)&#xff0c;可按以下步骤操作&#xff1a; 1. 检查是否已安装工具链 首先确认系统中是否已安装 arm-none-eabi-gcc&#xff1a; Windows&#xff1a;检查环境变量 PATH 中是否包含工具链路径…

Linux 系统 /etc/ 配置

在Linux系统中&#xff0c;/etc/ 目录是系统配置文件的核心存放位置&#xff0c;包含了各种系统服务、应用程序和硬件的配置信息。以下是该目录下常见的重要配置文件和子目录&#xff1a; 核心系统配置文件 /etc/hostname 系统主机名配置&#xff0c;直接决定当前系统的名称。/…

【跟着PMP学习项目管理】项目管理 之 成本管理知识点

目录 一、估算成本 1、知识点汇总 2、输入 3、工具 4、输出 二、预算成本 1、知识点汇总 2、输入 3、工具 4、输出 三、控制成本 1、知识点汇总 2、输入 3、工具 4、输出 一、估算成本 1、知识点汇总 1) 估算工具的用法 2、输入 范围基准、人力资源计划、项…

TCP相关实验

目录 TCP相关实验 理解CLOSE_WAIT状态 理解​​​TIME_WAIT状态 解决TIME_WAIT状态引起的bind失败的方法 理解listen的第二个参数 ​编辑 使用Wireshark分析TCP通信流程 TCP与UDP TCP与UDP对比 用UDP实现可靠传输&#xff08;经典面试题&#xff09; TCP相关实验 理解…

Spring Boot项目初始化:官方与阿里云服务地址对比指南

服务提供商 官方&#xff08;start.spring.io Spring&#xff09; 官方提供的服务&#xff0c;由Pivotal&#xff08;VMware&#xff09;维护&#xff0c;是标准的初始化工具。 阿里云&#xff08;start.aliyun.com&#xff09; 阿里云提供的国内镜像服务&#xff0c;针对中国开…

创客匠人创始人IP案例:从个人品牌到企业增长的全链路拆解

认知破局&#xff1a;为什么创客匠人创始人IP能撬动企业增长&#xff1f;在知识付费工具竞争同质化的当下&#xff0c;创客匠人创始人老蒋以“IP变现领军人”的IP形象&#xff0c;为企业打开了差异化增长通道。当同行还在比拼“功能数量”时&#xff0c;老蒋通过《领导者请停止…

UVC(USB Video Class,USB 视频类)协议

UVC&#xff08;USB Video Class&#xff0c;USB 视频类&#xff09;协议并非专门仅用于相机&#xff0c;但其核心应用场景集中在视频采集设备&#xff0c;相机是最典型的代表。其适用设备除了常见的 USB 相机&#xff08;包括 webcam、工业相机、监控摄像头等&#xff09;&…

如何使用 eBPF 监控 Linux 内存情况:Linux 内存调优之 eBPF 内存监控分析

写在前面 博文内容整理自 《BPF Performance Tools》 书中 内存部分对书中提到BPF工具配合实际Demo进行说明,以及一些变体的输出涉及下面一些内存问题的 BPF 观测 Demo:为什么进程的物理内存占用(RSS)不停增长?哪些代码路径会导致缺页错误的发生,缺页错误来自哪些文件?大页的…

SQL 表结构转 Go、Java、TS 自定义实体类,支持自编模板

SQL 表结构一键转自定义模型&#xff0c;支持 Golang Template 自由编写&#xff01; 有没有想过 —— 一份 SQL 表结构&#xff0c;不止能转成 Java 实体类、Go struct&#xff0c;甚至可以&#xff1a; ✨ 一键生成 TypeScript 接口✨ 输出 Protobuf 定义文件✨ 输出任意你…

新型BERT勒索软件肆虐:多线程攻击同时针对Windows、Linux及ESXi系统

趋势科技安全分析师发现&#xff0c;一个代号为BERT&#xff08;内部追踪名Water Pombero&#xff09;的新型勒索软件组织正在亚洲、欧洲和美国展开多线程攻击。该组织主要针对医疗保健、科技和会展服务行业&#xff0c;其活动范围显示其正成为勒索软件生态中的新兴威胁力量。攻…

Three.js搭建小米SU7三维汽车实战(1)搭建开发环境

1.基本概念 ![](https://i-blog.csdnimg.cn/img_convert/a4676122e207e058f3a335df2c99d4f8.png)1) 场景 如何理解场景 场景就是一个三维的世界, 在这个世界中可以放置各种各样的物体 可以理解成一个**空间**, 或者**容器** 2) 相机 如何理解相机 &#x1f914;**思考: *…

Selenium 原理【selenium】

Selenium 是什么&#xff1f;Selenium 是一个专门用于自动化操作网页的工具集&#xff0c;它能够模拟人类在浏览器中进行的各种操作&#xff0c;如点击按钮、填写表单、滚动页面等。借助 Selenium&#xff0c;开发者可以编写脚本来控制浏览器&#xff0c;实现自动化测试、数据采…

【音视频】HLS-m3u8协议介绍

参考文档&#xff1a;https://datatracker.ietf.org/doc/html/rfc8216 一、m3u8协议概述 m3u8 协议是基于 M3U 格式扩展而来的一种多媒体播放列表协议&#xff0c;主要用于流媒体的索引和分发&#xff0c;尤其在 HLS&#xff08;HTTP Live Streaming&#xff09;技术中扮演核…

unity入门:动画等不显示问题——画布设置

unity入门&#xff1a;动画等不显示问题——画布设置动画等不显示问题大部分原因画布Canvas总结动画等不显示问题大部分原因 1、画布设置渲染模式不对&#xff0c;下文再讲这个问题。 2、在层级双击动画查看动画大小&#xff0c;有些动画创建完之后在场景大小实际很小需要在R…