【数据结构与算法】线性表的查找

news2024/11/18 11:45:56

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:数据结构与算法
🌠 首发时间:2022年12月5日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🌟 一以贯之的努力 不得懈怠的人生

阅读指南

  • 查找
    • 基本概念
    • 对查找表的常见操作
    • 查找算法的评价指标
  • 顺序查找
    • 算法思想
    • 实现
    • 顺序查找的优化(对有序表)
    • 用查找判定树分析ASL
    • 顺序查找的优化(被查概率不相等)
  • 折半查找
    • 算法思想
    • 实现
    • 查找效率分析
    • 折半查找判定树的构造
    • 查找效率
  • 分块查找
    • 算法思想
    • 查找效率分析

查找

基本概念

查找 —— 在数据集合中寻找满足某种条件的数据元素的过程称为查找

查找表(查找结构) —— 用于查找的数据集合称为查找表,它由同一类型的数据元素(或记录)组成

关键字 —— 数据元素中唯一识别该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的

对查找表的常见操作

  1. 查找符合条件的数据元素
  2. 插入、删除某个数据元素

只需进行操作 1 1 1 的为静态查找表,我们只关注查找速度即可;

两种操作都要进行的为动态查找表,除了查找速度,我们也要关注插入或删除操作是否方便实现

查找算法的评价指标

查找长度 —— 在查找运算中,需要对比关键字的次数称为查找长度

平均查找长度( A S L , A v e r a g e   S e a r c h   L e n g t h ASL, Average \ Search \ Length ASL,Average Search Length)—— 所有查找过程中进行关键字的比较次数的平均值

平均查找长度计算方式如下:
A S L = ∑ i = 1 n P i C i ASL = \sum_{i=1}^{n}P_iC_i ASL=i=1nPiCi
其中, n n n 为数据元素的个数, P i P_i Pi 为查找第 i i i 个元素的概率, C i C_i Ci 为查找第 i i i 个元素的查找长度。通常情况下,默认查找任何一个元素的概率是相同的

A S L ASL ASL 的数量级反映了查找算法的时间复杂度,评价一个查找算法的效率时,通常需要考虑查找成功和查找失败两种情况的 A S L ASL ASL

顺序查找

算法思想

顺序查找,又称为线性查找,通常用于线性表,线性表又分为顺序表和链表两种

算法思想:从头到尾一个个找,或者反过来也行

实现

第一种方法(常规):

typedef struct{				//查找表的数据结构(顺序表)
	ElemType *elem;			//动态数组基址
	int TableLen;			//表的长度
}SSTable;

//顺序查找
int Search_Seq(SSTable ST, ElemType key) {
	int i;
	
	//当找到或者找完就会跳出循环
	for (i = 0; i < ST.TableLen && ST.elem[i] != key; ++i);
	
	//查找成功则返回元素下标;否则返回-1
	return i == ST.TableLen ? - 1 : i;	
}

第二种方法(哨兵):

此时数据从下标为 1 1 1 处开始存储, 0 0 0 处作为哨兵

typedef struct{				//查找表的数据结构(顺序表)
	ElemType *elem;			//动态数组基址
	int TableLen;			//表的长度
}SSTable;

//顺序查找
int Search_Seq(SSTable ST, ElemType key) {
	ST.elem[0] = key;		//将要查找的值存进 0 处
	int i;
	
	//从后遍历
	for (i = ST.TableLen; ST.elem[i] != key; --i);
	
	//查找成功则返回元素下标;否则返回0
	return i;	
}

优点:无需判断是否越界,效率更高

查找成功的 A S L ASL ASL 1 + 2 + 3 + ⋯ + n n = n + 1 2 \frac{1 + 2+3 + \cdots + n}{n} = \frac{n+1}{2} n1+2+3++n=2n+1

查找失败的 A S L ASL ASL n + 1 n + 1 n+1

顺序查找的优化(对有序表)

查找表中元素有序存放(递增 / 递减),例如 7   13   19   29   37   43 7 \ 13 \ 19 \ 29 \ 37 \ 43 7 13 19 29 37 43,当我们要找 21 21 21 这个值时,一共有 n + 1 n+1 n+1 种查找失败的情况,此时查找失败的 A S L ASL ASL 1 + 2 + 3 + ⋯ + n + n n + 1 = n 2 + n n + 1 \frac{1 + 2+3 + \cdots + n + n}{n+1} = \frac{n}{2} + \frac{n}{n+1} n+11+2+3++n+n=2n+n+1n

在这里插入图片描述

用查找判定树分析ASL

在这里插入图片描述

一个成功结点的查找长度 = 自身所在层数

一个失败结点的查找长度 = 其父节点所在层数

默认情况下,各种失败情况或成功情况都等概率发生

顺序查找的优化(被查概率不相等)

如果每个元素的被查概率不相等,我们可以将被查概率大的放在靠前位置,这样可以减小查找成功的 A S L ASL ASL

折半查找

算法思想

折半查找,又称为 “二分查找”,仅适用于有序的顺序表

实现

以下代码基于数据是存储在升序的顺序表

typedef struct{				//查找表的数据结构(顺序表)
	ElemType *elem;			//动态数组基址
	int TableLen;			//表的长度
}SSTable;

//折半查找
int Binary_Search(SSTable L, ElemType key) {
	int low = 0, high = L.TableLen - 1, mid;
	while (low <= high) {
		mid = (low + high) / 2;		//取中间位置
		if (L.elem[mid] == key) 
			return mid;				//查找成功返回所在位置
		else if (L.elem[mid] > key)
			high = mid - 1;			//中间值比查找值要大
		else 
			low = mid + 1;			//中间值比查找值要小
	}
	return -1;		//查找失败
}

查找效率分析

假设有如下顺序表:

在这里插入图片描述

经过折半查找,我们可以得到一个它的查找判定树:

在这里插入图片描述

注:绿色部分为查找成功,紫色部分为查找失败

成功的平均查找长度为: ( 1 × 1 + 2 × 2 + 3 × 4 + 4 × 4 ) / 11 = 3 (1 \times 1 + 2 \times 2 + 3 \times 4 + 4 \times 4) / 11 = 3 (1×1+2×2+3×4+4×4)/11=3

失败的平均查找长度为: ( 3 × 4 + 4 × 8 ) / 12 = 11 / 3 (3 \times 4 + 4 \times 8) / 12 = 11/3 (3×4+4×8)/12=11/3

折半查找判定树的构造

  • 如果当前 l o w low low h i g h high high 之间有奇数个元素,则 m i d mid mid 分隔后,左右两部分元素个数相等

  • 如果当前 l o w low low h i g h high high 之间有偶数个元素,则 m i d mid mid 分隔后,左半部分比右半部分少一个元素

基于以上两个结论,我们可以得到下面的推论:

  • 折半查找的判定树中,若 m i d = ⌊ ( l o w + h i g h ) / 2 ⌋ mid = \lfloor(low + high)/2 \rfloor mid=(low+high)/2,则对于任何一个结点,必有 —— 右子树结点数 − - 左子树结点数 = 0 = 0 =0 1 1 1

所以我们可以得到 1 ∼ 16 1 \sim 16 116 个元素的折半查找判定树如下:

在这里插入图片描述
(注:图中的数字只是一个编号,不是值)

折半查找的判定树一定是平衡二叉树

折半查找判定树中,只有最下面一层是不满的,因此,元素个数为 n n n 时树高 h = ⌈ l o g 2 ( n + 1 ) ⌉ h = \lceil log_2(n + 1)\rceil h=log2(n+1)(注:计算方法同 “完全二叉树”)

判定树结点关键字:左 < 中 < 右,满足二叉排序树的定义

若成功结点为 n n n 个,则失败结点为 n + 1 n + 1 n+1 个(等于成功结点的空链域数量)

查找效率

树高 h = ⌈ l o g 2 ( n + 1 ) ⌉ h = \lceil log_2(n + 1)\rceil h=log2(n+1)

查找成功的 A S L ≤ h ASL \leq h ASLh,查找失败的 A S L ≤ h ASL \leq h ASLh

所以折半查找的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)

分块查找

算法思想

在这里插入图片描述

如上图,下面是顺序表,上面是对应的索引表,索引表中保存了每个分块的最大关键字和分块的存储区间

特点:块内无序,块间有序

//索引表
typedef struct{
	ElemType maxValue;
	int low, high;
}Index;

//顺序表存储实际元素
ElemType List[100];

分块查找,又称为索引顺序查找,算法过程如下:

  1. 在索引表中确定待查记录所属的分块(可顺序、可折半)
  2. 在块内顺序查找

在进行折半查找所属分块时,如果索引表中不包含目标关键字,则折半查找索引表最终停在 l o w > h i g h low > high low>high,这时候我们要在 l o w low low 所指分块中查找

  • 原因:最终 l o w low low 左边一定小于目标关键字, h i g h high high 右边一定大于目标关键字,而分块存储的索引表中保存的是各个分块的最大关键字

查找效率分析

在这里插入图片描述

假设,长度为 n n n 的查找表被均匀地分为 b b b 块,每块 s s s 个方块

设索引查找和块内查找的平均查找长度分别为 l I l_I lI L s L_s Ls,则分块查找的平均查找长度为
A S L = l I + L s ASL = l_I + L_s ASL=lI+Ls
用顺序表查找索引表,则 L I = ( 1 + 2 + ⋯ + b ) b = b + 1 2 L_I = \frac{(1 + 2 + \dots + b)}{b} = \frac{b + 1}{2} LI=b(1+2++b)=2b+1 L s = ( 1 + 2 + ⋯ + s ) s = s + 1 2 L_s = \frac{(1 + 2 + \dots + s)}{s} = \frac{s + 1}{2} Ls=s(1+2++s)=2s+1,那么 A S L = b + 1 2 + s + 1 2 = s 2 + 2 s + n 2 s ASL = \frac{b + 1}{2} + \frac{s + 1}{2} = \frac{s^2 + 2s + n}{2s} ASL=2b+1+2s+1=2ss2+2s+n,当 s = n s = \sqrt{n} s=n 时, A S L ASL ASL 最小,为 n + 1 \sqrt{n} + 1 n +1

用折半查找查索引表,则 L I = ⌈ l o g 2 ( b + 1 ) ⌉ , L s = ( 1 + 2 + ⋯ + s ) s = s + 1 2 L_I = \lceil log_2(b + 1) \rceil, L_s = \frac{(1 + 2 + \cdots + s)}{s} = \frac{s + 1}{2} LI=log2(b+1),Ls=s(1+2++s)=2s+1, 则 A S L = ⌈ l o g 2 ( b + 1 ) ⌉ + s + 1 2 ASL = \lceil log_2(b + 1) \rceil + \frac{s + 1}{2} ASL=log2(b+1)+2s+1

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

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

相关文章

Java入门教程(5)——开发第一个Java程序

文章目录1.1. 新建一个记事本&#xff0c;将后缀名改为java 如图示&#xff1a; 2.双击&#xff0c;选择打开方式为记事本 输入代码&#xff1a; public class HelloWorld{public static void main(String[] args){System.out.println("Hello world&#xff01;");…

基于DIPUM工具箱对图书数字图像进行处理(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 数字图像处理(Digital Image Processing)将图像信号转换成数字信号并利用计算机对其进行处理,起源于20世纪20年代,目前已广泛地…

电脑硬盘就一个c盘怎么分区,新电脑买回来只有一个c盘怎么分区

电脑硬盘就一个c盘怎么分区&#xff1f;为了方便存储数据&#xff0c;需要对磁盘分区那么&#xff0c;在本文中&#xff0c;易我小编将讲解电脑磁盘分区的实操方法。 一、Diskpart对C盘分区 在Windows操作系统中&#xff0c;Diskpart是命令提示符&#xff0c;可以实现创建分区…

安全面试之基础总结篇【超详细!】

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽的博客_CSDN博客-网络安全,CTF,内网渗透领域博主 安全面试专栏&#xff1a;https://blog.csdn.net/m0_63127854/category_11869916.html 网络安全交流社区&#xff1a;https:…

华为网络模拟器ENSP安装(附安装包)

一、安装前注意事项 1、安装路径 以下所有软件,安装时不建议修改默认路径,尤其ENSP绝对不能安装在电脑主机的中文路径下,否则没法启动。 2、先安装依赖软件 VirtualBox不能安装目录不能有中文,只能装5.0至5.2版本。 WireShark为驱动级软件,需要重启生效,可以在三个软…

WebDAV之葫芦儿·派盘+恒星播放器

恒星播放器 支持WebDAV方式连接葫芦儿派盘。 想要拥有一款万能视频播放器,全能解码播放器,无需转码,支持所有格式的视频和音频,直接播放的播放器?那就选恒星播放器。 恒星播放器支持视屏投屏,倍速播放,后台播放等功能,还能一键截图和录制gif动图。支持全格式超高清真…

企业架构MySQL数据库架构读写分离

学习目标与内容 运维解决方案 读写分离常见的实现方式 MySQL读写分离案列实现 主从复制master配置 主从复制slave配置 简单业务代码实现 用以下代码通过停启主从服务器来检查主从复制原理~ <?php //创建类 class Mysql {//构造方法//当类被实例化时,会触发此方法public fu…

[附源码]Python计算机毕业设计Django居家养老服务系统小程序

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]计算机毕业设计JAVA疫情居家隔离服务系统

[附源码]计算机毕业设计JAVA疫情居家隔离服务系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

【webrtc】PacketBuffer的VCMPacket管理

代码应该是m79.PacketBuffer 只是作为RtpVideoStreamReceiver 的一个成员变量出现,看起来并不重要,但是对于rtp包来说,非常重要:video_coding::PacketBuffer packet_buffer_;PacketBuffer::InsertPacket(VCMPacket* packet) 输入和输出 输入的是VCMpacket的指针 ,InsertPa…

线程池详解

一、概念 1、线程池管理器&#xff1a;用于创建并管理线程池&#xff0c;包括创建线程池&#xff0c;销毁线程池&#xff0c;添加新任务&#xff1b; 2、工作线程&#xff1a;线程池中线程&#xff0c;可以循环的执行任务&#xff0c;在没有任务时处于等待状态&#xff1b; …

Python 采集87个手绘风格PPT模板

源码下载链接&#xff1a;ppt.rar - 蓝奏云 PPT下载链接&#xff1a;https://pan.baidu.com/s/1HUAEe_-4IEV6ttOKC_VPuA?pwd96px 提取码&#xff1a;96px 采集的参数 page_count 1 # 每个栏目开始业务content"text/html; charsetgb2312"base_url "https:…

网络层之IP协议(必备知识)

文章目录1、IP协议头格式2、IP分片与组装4、IP基础知识<1>IP地址属于网络层地址<4>IP地址<2>路由控制<3>IP属于面型无连接型4、其他重要协议或技术<1>ICMP协议TCP/IP的心脏是互联网。这一层主要由IP(Internet Protocal) 和ICMP(Internet Control…

短视频内容创作:内容发给谁?为什么发?发什么?以什么形式发?

一句话介绍短视频内容定位&#xff0c;我赢助手每周一课短视频运营关键节点介绍。 内容定位无非就是视频发给谁?为什么发?以什么形式发&#xff1f; 短视频发给谁&#xff1f;就是做好你的目标受众的细分。 商业定位我们之前聊过了&#xff0c;如果你看过之前的内容&#x…

双十二护眼灯牌子买什么的好?几款比较好的学生护眼灯推荐

双十二即将来临&#xff0c;相信很多小伙伴们也开始着手选择比较喜欢的东西了吧&#xff0c;那对于学生来讲&#xff0c;护眼台灯也是一个不可忽视的好东西。 现在的学习压力这么大&#xff0c;用眼过于频繁&#xff0c;所以很多学生孩子眼睛就很容易近视&#xff0c;小小年纪就…

MATLAB实现希尔伯特变换以及FFT补零分析

南京信息工程大学 实验&#xff08;实习&#xff09;报告 实验&#xff08;实习&#xff09;名称 数字信号处理 实验&#xff08;实习&#xff09;日期 得分 指导老师 学院 电信院 专业 电子信息工程 年级 2020 班次 …

从vue2到vue3,生命周期函数有何变化之详解

vue2与vue3生命周期的对比&#xff1a; Vue2--------------Vue3 beforeCreate—————–>setup() created————————>setup() beforeMount—————–>onBeforeMount mounted—————-------> onMounted beforeUpdate -————–> onBeforeUpdate u…

正则表达式入门级别详细教程

文章目录常用正则表表达式01、火车车次02、手机机身码(IMEI)03、必须带端口号的网址(或ip)04、网址(URL)05、统一社会信用代码06、迅雷/ed2k/磁力链接07、子网掩码(不包含 0.0.0.0)08、Linux/windows文件路径09、股票代码(A股)10、大于等于0, 小于等于150, 支持小数位出现5, 如…

手把手教你编写Python抢购脚本

想买苹果手机&#xff0c;但总是抢不到&#xff0c;所以想试着能不能写个脚本代码。 第一步&#xff1a;把想要抢购的商品加进购物车&#xff0c;注意&#xff1a;脚本是对购物车内全部商品进行下单操作&#xff0c;所以不够买的商品最好先从购物车内删除。 第二步&#xff1a…

网络安全这玩意儿真不建议一般人学...

前言 作为一名5年网安工程师老菜鸟来说&#xff0c;我实在想不通&#xff0c;开发岗位那么多&#xff0c;为什么要来学网安? 在这里怕是要给准备入坑的同学泼盆冷水了&#xff0c;网络安全这东西真不建议一般人学... 基础确实很简单&#xff0c;是个人稍微认点真都能懂&…