数据结构——查找算法

news2024/9/25 19:22:27

文章目录

1. 查找算法

2. 顺序查找

2. 二分查找


1. 查找算法

查找算法是用于在数据集中定位特定元素的位置的算法。查找是计算机科学中一项基本操作,几乎在所有应用程序中都需要使用。例如,数据库查询、信息检索、字典查找等都涉及到查找操作。查找算法可以根据不同的需求和数据结构选择不同的实现方法,以达到高效、准确的目的。

顺序查找

原理:从数据集的起始位置开始,依次检查每个元素,直到找到目标元素或到达数据集末尾。

优点:实现简单。无需数据集有序。

缺点:查找效率较低,时间复杂度为O(n)。

二分查找

原理:在有序数据集中,通过反复将查找范围减半,逐步缩小搜索范围,直到找到目标元素或确定目标元素不存在。

优点

  • 查找效率较高,时间复杂度为O(log n)。
  • 适用于有序数据集。

缺点

  • 需要数据集有序。
  • 实现相对复杂。

2. 顺序查找

顺序查找,又称线性查找,是一种最基本的查找算法。它的工作原理非常简单,主要步骤如下:

  1. 从头开始遍历:从数据集的起始位置开始,依次检查每个元素。
  2. 比较目标:对于每个遍历到的元素,将其与目标元素进行比较。
  3. 查找成功:如果当前元素等于目标元素,则查找成功,返回当前元素的索引。
  4. 查找失败:如果遍历完整个数据集仍未找到目标元素,则查找失败,返回一个特殊的标识来表示未找到。

这种方法的优点在于简单直观,但对于大量数据来说,效率不高,因为它在最坏情况下需要检查每个元素。

伪代码

function linearSearch(array, target):
    for index from 0 to length(array) - 1:
        if array[index] == target:
            return index  // 查找成功,返回索引
    return -1  // 查找失败,返回特殊标识

C代码实现

#include <stdio.h>

// 顺序查找函数
// arr[]: 待查找的数组
// n: 数组的长度
// target: 目标元素
int linearSearch(int arr[], int n, int target) {
    // 遍历数组中的每个元素
    for (int i = 0; i < n; i++) {
        // 如果当前元素等于目标元素
        if (arr[i] == target) {
            return i;  // 查找成功,返回当前元素的索引
        }
    }
    return -1;  // 查找失败,返回特殊标识 -1 表示未找到目标元素
}

int main() {
    int arr[] = {3, 5, 7, 9, 11, 13, 15};  // 定义一个整数数组
    int n = sizeof(arr) / sizeof(arr[0]);  // 计算数组的长度
    int target = 9;  // 定义目标元素

    // 调用顺序查找函数查找目标元素
    int result = linearSearch(arr, n, target);

    // 根据查找结果输出相应的信息
    if (result != -1) {
        printf("元素 %d 在数组中的索引为: %d\n", target, result);  // 查找成功
    } else {
        printf("元素 %d 不在数组中\n", target);  // 查找失败
    }

    return 0;  // 程序结束
}
  • 函数定义linearSearch 函数接收一个数组、数组长度和目标元素作为参数。
  • 遍历数组:使用 for 循环遍历数组中的每个元素。
  • 比较元素:在循环中,将每个元素与目标元素进行比较。如果相等,则返回当前索引。
  • 查找失败:如果循环结束后仍未找到目标元素,则返回 -1 表示查找失败。
  • 主函数:在 main 函数中,定义了一个数组和目标元素,调用 linearSearch 函数,并根据返回结果输出相应的信息。

2. 二分查找

二分查找(Binary Search)是一种高效的查找算法,通常用于在有序数据集中查找目标元素。其原理是通过将数据集划分为两半并与目标进行比较,以确定目标在哪一半中,从而逐步缩小搜索范围,直到找到目标元素或确定不存在目标元素。基本原理如下:

1. 选择中间元素:在有序数据集中,选择数组的中间元素。

  • 初始时,选择整个数组的中间元素。对于一个有序数组arr,如果当前的搜索范围是[low, high],则中间元素的位置是mid = (low + high) / 2

2. 比较目标:将中间元素与目标元素进行比较。

  • 将数组中间位置的元素arr[mid]与目标元素target进行比较。

3. 查找成功:如果中间元素等于目标元素,则查找成功,返回中间元素的索引。

  • 如果arr[mid] == target,则找到目标元素,返回mid

4. 缩小搜索范围

  • 对于一个升序的数据集,如果中间元素大于目标元素,说明目标可能在左半部分;如果中间元素小于目标元素,说明目标可能在右半部分。根据比较结果,将搜索范围缩小到左半部分或右半部分,继续查找。
  • 如果arr[mid] > target,则目标元素在左半部分,即更新搜索范围为[low, mid - 1]
  • 如果arr[mid] < target,则目标元素在右半部分,即更新搜索范围为[mid + 1, high]

5. 重复步骤:重复上述步骤,不断将搜索范围缩小,直到找到目标元素或搜索范围为空。

  • 重复上述步骤,直到low > high(搜索范围为空)或找到目标元素。

C代码实现

#include <stdio.h>

// 二分查找函数
int binarySearch(int arr[], int low, int high, int target) {
    while (low <= high) {
        int mid = (low + high) / 2; // 选择中间元素
        if (arr[mid] == target) {
            return mid; // 查找成功,返回索引
        } else if (arr[mid] > target) {
            high = mid - 1; // 缩小搜索范围到左半部分
        } else {
            low = mid + 1; // 缩小搜索范围到右半部分
        }
    }
    return -1; // 查找失败,返回特殊值
}

int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 5;
    int result = binarySearch(arr, 0, n - 1, target);
    if (result != -1) {
        printf("Element found at index: %d\n", result);
    } else {
        printf("Element not found in array\n");
    }
    return 0;
}
  • 时间复杂度:二分查找的时间复杂度是O(log n),因为每次比较后搜索范围都会减少一半。
  • 空间复杂度:由于二分查找只需要几个额外的变量存储索引,因此空间复杂度是O(1)

假设我们有一个有序数组arr = {1, 2, 3, 4, 5, 6, 7, 8},目标元素是5

  1. 初始时,low = 0high = 7,计算mid = (0 + 7) / 2 = 3

    • 比较arr[3](即4)与目标5
    • 因为4 < 5,所以目标在右半部分,更新low = 4
  2. 下一步,low = 4high = 7,计算mid = (4 + 7) / 2 = 5

    • 比较arr[5](即6)与目标5
    • 因为6 > 5,所以目标在左半部分,更新high = 4
  3. 最后,low = 4high = 4,计算mid = (4 + 4) / 2 = 4

    • 比较arr[4](即5)与目标5
    • 因为5 == 5,查找成功,返回索引4

因此,目标元素5在数组中的索引是4

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

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

相关文章

【Mutilism数字电路实现32进制5线32译码器】2022-5-7

缘由3-8译码器到74HC138-编程语言-CSDN问答 2片16004非门2个组成8进制和4进制实现。 按138逻辑表把E3也接入置零&#xff0c;同时把E1也接入反向使得切换时138保持高电平输出&#xff0c;就看不到转换时第一个出现短暂低电平&#xff0c;是最完美的解决方案&#xff0c;二级反向…

分布式I/O从站的认知

为什么需要分布式I/O从站&#xff1f; 当PLC与控制机构距离过远时&#xff0c;远距离会带来信号干扰&#xff0c;分布式I/O从站只需要一个网络线缆连接。 ET200分布式I/O从站家族 体积紧凑、功能强大。 ET200SP ET200M ET200S ET200iSP ET200 AL ET200pro ET200 eco PN 通讯协议…

yarn底层原理详解:(第33天)

系列文章目录 一、yarn总体架构 二、yarn核心组件及功能 三、yarn资源分配与调度 四、yarn提交和执行流程 五、yarn调度算法 六、yarn安全性与容错性 文章目录 系列文章目录前言一、总体架构二、核心组件及功能1. ResourceManager&#xff08;RM&#xff09;2. NodeManager&am…

达梦数据库dm8安装步骤及迁移

目录 前言: 一、安装部署 1、下载 2、创建用户及安装目录 3、挂载下载的镜像 4、环境配置 5、安装 二、基本使用 1、DM工具使用 2、兼容性配置 2.1 兼容GBK字符集编码 2.2 兼容UTF-8字符集编码 3、创建用户和密码,表空间 4、整理数据库配置 5、启动脚本设置 …

13、Python之函数:简单的参数默认值其实并不简单

目录 引言 日志打印的问题 返回参数默认值的问题 问题产生的原因 关于参数默认值的最佳实践 总结 引言 在前一篇关于Python函数的文章中&#xff0c;我们介绍了函数的基本使用、函数的默认参数、lambda函数的用法&#xff0c;相当于对Python中的函数有了一个入门的介绍。…

动态规划之数字三角形模型+最长上升子序列模型

首先&#xff0c;我们从集合角度重新看待DP&#xff1a; 直接看题&#xff1a;https://www.acwing.com/problem/content/1029/ 就是取纸条的原题&#xff0c;我们令f[i1,j1,i2,j2]表示从(1,1),(1,1)分别走到(i1,j1),(i2,j2)的路径的max i1j1i2j2&#xff0c;于是我们可以把状…

ESP32的芯片有几种

ESP32系列 ESP32芯片截止到24年7月有5个系列&#xff1a; ESP32-C3 ESP32由ESP32-P 系列、ESP32-S 系列、ESP32-C 系列、ESP32-H 系列、ESP32 系列构成。其中ESP32-S分为S3和S2两个小系列&#xff1b;ESP32-C系列分为C6、C5、C3、C2四个小系列&#xff0c;具体如下。 说明&am…

合宙 Air780E模块 AT 指令 MQTT连接

固件说明 重启模块 //tx ATRESET//rx ATRESETOK ^boot.romv!\n RDY^MODE: 17,17E_UTRAN ServiceCGEV: ME PDN ACT 1NITZ: 2024/07/10,08:33:440,0查询模块版本信息 //tx ATCGMR//rx ATCGMRCGMR: "AirM2M_780E_V1161_LTE_AT"OK基本流程 4G模块支持MQTT和MQTT SSl协…

5 MySql

5 MySql 一、简介二、SQL语言2.1 导入外部SQL文件2.2 显示表结构2.3 与创建数据库相关的语句2.4 与表相关的语句2.5 操作表中的数据2.6 7种基本的sql查询 三、SQL的注意点3.1 与集合函数相关3.2 SQL语句的书写与执行过程 四、约束 constraint4.1 作用4.2 功能分类4.3 自增 五、…

读人工智能全传10深度思维

1. 深度思维 1.1. DeepMind 1.1.1. 深度思维 1.1.2. 2014年的员工不足25人 1.1.3. 深度思维公司公开宣称其任务是解决智能问题 1.1.4. 2014年谷歌收购DeepMind&#xff0c;人工智能突然成了新闻热点&#xff0c;以及商业热点 1.1.4.1. 收购报价高达4亿英镑 1.1.4.2. 深度…

差分约束——AcWing 362. 区间

差分约束 定义 差分约束系统是一种在计算机科学和运筹学中用于解决特定类型优化问题的工具。它主要用于处理一类线性不等式组&#xff0c;这些不等式描述了变量之间的相对大小关系&#xff0c;而不是直接的绝对值大小。差分约束系统通常用于路径寻找、调度、资源分配等问题。…

maven私有镜像仓库nexus部署使用

maven私有镜像仓库nexus部署使用 1、Nexus部署 #查找镜像 docker search sonatype/nexus3 #拉取镜像 docker pull sonatype/nexus3 #持久化目录 mkdir -p /data/nexus/data chmod 777 -R /data/nexus/data #启动服务 docker run -d --name nexus3 -p 8081:8081 --restart alw…

javaweb基础知识入门

javaweb 1.基本概念 1.1前言 web开发&#xff1a; web&#xff0c;网页的意思&#xff0c;www.baidu.com 静态web html&#xff0c;css 提供给所有人看的数据始终不会发生变化&#xff01; 动态web 淘宝...等几乎是所有的网站 提供给所有人看的数据始终会发生变化&#…

mac生成.dmg压缩镜像文件

mac生成.dmg压缩镜像文件 背景准备内容步骤1&#xff0c;找一个文件夹2&#xff0c;制作application替身1&#xff0c;终端方式2&#xff0c;黄金右手方式 3&#xff0c;.app文件放入文件夹4&#xff0c;制作.dmg压缩镜像文件5&#xff0c;安装.dmg 总结 背景 为绕开App Store…

头歌资源库(27)特别的数

一、 问题描述 编程输出一个特别的数&#xff0c;该数是一个由1~9组成的9位数&#xff0c;每个数字只能出现一次&#xff0c;且这个9位数由高位到低位前i位能被i整除。 二、算法思想 创建一个长度为9的数组&#xff0c;用于存放1~9这9个数字。使用回溯算法&#xff0c;从第…

Visual Studio 2019 (VS2019) 中使用 CMake 配置 OpenCV 库(快捷版)

2024.07.11 测试有效 最近需要用一下 opencv 处理图像&#xff0c;简单配置了一下Cmake下的 opencv 库。 没有编译 opencv &#xff0c;也不知道他们为什么要自己编译 opencv 。 一、下载并安装 OpenCV 1.前往 OpenCV 官方网站 下载适用于您的系统的 OpenCV 安装包。 2.点击直接…

在分布式环境中,怎样保证 PostgreSQL 数据的一致性和完整性?

文章目录 在分布式环境中保证 PostgreSQL 数据的一致性和完整性一、数据一致性和完整性的重要性二、分布式环境对数据一致性和完整性的挑战&#xff08;一&#xff09;网络延迟和故障&#xff08;二&#xff09;并发操作&#xff08;三&#xff09;数据分区和复制 三、保证 Pos…

PFH点特征直方图

PFH特征描述子原理 该算法通过参数化查询关键点与其周围邻域点之间的空间差异,形成一个多维度直方图,从而实现对该点的邻域几何属性的描述。 该方法具有以下三个优势: (1)刚性变换不变性,即不受旋转、平移变换的影响; (2)采样一致性,即改变采样密度,特征保…

【高中数学/指数函数、对数函数、正弦函数】求 y=2^x+x,y=log2_x+x,y=2*sinX+x 的零点位置大小关系

【问题】 已知函数f(x)2^xx,g(x)log2_xx,h(x)2*sinXx 的零点分别是a,b,c,则a、b、c的大小顺序是&#xff1f; 【解答】 粗览三个函数&#xff0c;h(x)2*sinXx的零点是最好解决的&#xff0c;明显x0时h(x)0&#xff0c;因此c在原点的位置&#xff1b; 对于f(x)2^xx&#xff…

css预编译器--sass

Sass Sass 提供了 变量&#xff08;variables&#xff09;、嵌套规则&#xff08;nested rules&#xff09;、 混合&#xff08;mixins&#xff09;、 函数&#xff08;functions&#xff09;&#xff0c;目前我使用最多的还是变量和嵌套规则&#xff0c;貌似目前css也支持嵌套…