22.查找,线性表的查找

目录

一. 查找的基本概念

二. 线性表的查找

(1)顺序查找(线性查找)

(2)折半查找(二分或对分查找)

(3)分块查找


一. 查找的基本概念

查找表是由同一类型的数据元素(或记录)构成的集合。由于“集合”中的数据元素之间存在着松散的关系,因此查找表是一种应用灵便的结构。例如:每个同学的考号和成绩。

查找——根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或(记录)。

关键字用来标识一个数据元素(或记录)的某个数据项的值。

  • 主关键字:可唯一地标识一个记录的关键字是主关键字;(如:准考证号,每个准考证号唯一确定一名考生)
  • 次关键字:反之,用以识别若干记录的关键字是次关键字。(如:物理成绩,可能物理同一分数有很多人)

若查找表中存在这样一个记录,则称“查找成功”。查找结果给出整个记录的信息,或指示该记录在查找表中的位置;否则称“查找不成功”。查找结果给出“空记录”或“空指针”。

对查找表经常进行的操作:

  • 查询某个“特定的”数据元素是否在查找表中;
  • 检索某个“特定的”数据元素的各种属性;
  • 在查找表中插入一个数据元素;
  • 删除查找表中的某个数据元素。

查找表可以分为两类。静态查找表是仅作查询”(检索)操作的查找表。动态查找表是作"插入”和“删除”操作的查找表。有时在查询之后,还需要将查询结果为“不在查找表中”的数据元素插入到查找表中;或者,从查找表中删除其“查询”结果为“在查找表中”的数据元素,此类表为动态查找表。

查找算法的评价指标:关键字的平均比较次数,也称平均查找长度ASL(Average Search Length)ASL=\sum_{i=1}^{n}p_ic_i;其中:n:记录的个数;pi:查找第i个记录的概率(通常认为pi =1/n);ci:找到第i个记录所需的比较次数;

查找的方法取决于查找表的结构,即表中数据元素是依何种关系组织在一起的。由于对查找表来说,在集合中查询或检索一个“特定的”数据元素时,若无规律可循,只能对集合中的元素一一加以辨认直至找到为止。而这样的“查询”或“检索”是任何计算机应用系统中使用频度都很高的操作,因此设法提高查找表的查找效率,是本节讨论问题的出发点。为提高查找效率,一个办法就是在构造查找表时,在集合中的数据元素之间人为地加上某种确定的约束关系。

二. 线性表的查找

(1)顺序查找(线性查找)

应用场景:顺序表或线性链表表示的静态查找表,表内元素之间无序。

数据元素类型定义如下:

typedef struct{KeyType key;  //关键字域int math;  //其他域
}ElemType;typedef struct {  //顺序表结构类型定义ElemType *R;  //表基址int length;  //表长
}SSTable;  //Sequential Search TableSSTable ST;  //定义顺序表ST

我们从后往前比较,不难写出顺序查找的算法:

int Search_Seq(SSTable ST, KeyType key){  //Keytype根据问题需要自己设置//若成功返回其位置信息,否则返回0for(i=ST.length; i>=1; --i)if (ST.R[i].key==key) return i;  //ST.R[i].key就是i元素的Key值return 0;
}

当然这个算法有很多其他形式,这里给出一种:

int Search_Seq(SSTable ST,KeyType key){for (i = ST.length; ST.R[i].key != key; --i);  //注意后面有分号if (i <= 0) break;if (i > 0) return i;else return 0;
}

上述算法的每一个元素都要判断两次:一是i是否大于1,二是元素是否相等。我们可否简化一下比较步骤?我们把待查关键字key存入表头(“哨兵”、”监视哨”),从后往前逐个比较,可免去查找过程中每一步都要检测是否查找完毕,加快速度。这样,若表中不存在,则返回结果自然是0,就取消了检查越界的操作。

int Search_Seq(SSTable ST,KeyType key){ST.R[0].key = key;for (i = ST.length; ST.R[i].key != key; --i);  //注意后面有分号return i;
}

下面分析顺序查找法的时间效率。比较次数与key位置有关:查找第i个元素,需要比较n-i+1次;查找失败,需比较n+1次。所以,算法的时间复杂度是O(n),查找成功时的平均查找长度是:

ASL=\sum_{i=1}^{n}p_ic_i=\frac{1}{n}\sum_{i=1}^{n}(n-i+1)=\frac{n+1}{2}

空间复杂度:一个辅助空间O(1);

讨论:(1)记录的查找概率不相等时如何提高查找效率?
查找表存储记录原则——按查找概率高低存储:查找概率越高,比较次数越少;查找概率越低,比较次数较多。
(2)记录的查找概率无法测定时如何提高查找效率?
方法——按查找概率动态调整记录顺序:

  • 在每个记录中设一个访问频度域;
  • 始终保持记录按非递增有序的次序排列;
  • 每次查找后均将刚查到的记录直接移至表头。

(3)顺序查找法的优点:算法简单,逻辑次序无要求,且不同存储结构均适用。缺点:ASL太长,时间效率太低。

(2)折半查找(二分或对分查找)

特点:针对有序序列,每次将待查区间的长度缩小一半。

设表长为n,low、high和mid分别指向待查元素所在区间的上界、下界和中点,key为给定的要查找的值:

  • 初始时,令low=1,high=n,mid=L(low+high)/2];
  • 让k与mid指向的记录比较若key==R[mid].key,查找成功;若key<R[mid].key,则high=mid-1;若key>R[mid].key,则 low=mid+1;
  • 重复上述操作,直至low>high时,查找失败;
int Search_Bin (SSTable ST,KeyType key){low = 1; high = ST.length;  //置区间初值while (low <= high){mid = (low + high)/ 2;if (ST.R[mid].key == key) return mid; //找到待查元素else if (key < ST.R[mid].key)  //缩小查找区间high = mid - 1;  //继续在前半区间进行查找else low = mid + 1;  //继续在后半区间进行查找}return 0;  //顺序表中不存在待查元素
}  //Search_Bin

我们也可以用递归方法书写:

int Search_Bin(SSTable ST, keyType key, int low, int high){if(low > high) return 0;  //查找不到时返回0mid = (low+high)/2;if(key == ST.elem[mid].key) return mid;else if(key<ST.elem[mid].key)Search_Bin(ST, key, low, mid-1);  //递归,在前半区间进行查找elseSearch_Bin(ST, key, mid+1, high);  //递归,在后半区间进行查找
}

下面分析折半查找法的性能。分析每个位置需要查找几次,我们可以画出判定树:

假设表长n=2^h-1,则有h=log_2(n+1),此时判定树是高度为h的满二叉树。且假设表中每个元素查找的概率相等,p=\frac{1}{n}。不难得到:

ASL_{bs}=\frac{1}{n}\sum_{j=1}^{h}j\cdot 2^{j-1}=\frac{(h-1)2^h+1}{n}=\frac{n+1}{n}log_2(n+1)-1\approx log_2(n+1)-1(n>50)

折半查找优点:效率比顺序查找高。时间复杂度是O(lg n);
折半查找缺点:只适用于有序表,且限于顺序存储结构(对线性链表无效)。

(3)分块查找

举例:查字典,字典的编写把A-Z分成26块。分块查找的实质是索引顺序表上的查找。

方法:(1)将表分成几块,且分块有序(若i<j,则第j块中所有记录的关键字均大于第i块中的最大关键字),每块内的元素可以有序或无序;
(2)建立“索引表”(每个结点含有最大关键字域和指向本块第一个结点的指针,且按关键字有序)。

优点:插入和删除比较容易(本体链表,索引表顺序表),无需进行大量移动。
缺点:要增加一个索引表的存储空间并对初始索引表进行排序运算。
适用情况:如果线性表既要快速查找又经常动态变化,则可采用分块查找。

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

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

相关文章

macbookpro如何清理系统数据 macbookpro怎么删除软件

Macbook Pro是苹果公司的一款高性能笔记本电脑&#xff0c;它拥有强大的硬件和流畅的操作系统。然而&#xff0c;随着时间的推移&#xff0c;你可能会发现你的Macbook Pro变得越来越慢&#xff0c;储存空间也越来越紧张。这时候&#xff0c;你需要对你的Macbook Pro进行一些清理…

【Java从0到1学习】11 Java集合框架

1. Collection 1.1 Java类中集合的关系图 1.2 集合类概述 在程序中可以通过数组来保存多个对象&#xff0c;但在某些情况下开发人员无法预先确定需要保存对象的个数&#xff0c;此时数组将不再适用&#xff0c;因为数组的长度不可变。例如&#xff0c;要保存一个学校的学生信…

Redis 为什么这么快?

前言 作为一名后端软件工程师&#xff0c;工作中你肯定和 Redis 打过交道。但是Redis 为什么快呢&#xff1f;很多人只能答出Redis 因为它是基于内存实现的&#xff0c;但是对于其它原因都是模棱两可。 那么今天就一起来看看是Redis 为什么快吧&#xff1a; Redis 为什么这么快…

vue与vueComponent的关系

创建完组件之后 就会创建一个vueComponent构造函数 当注册成功这个组件并且在页面使用之后 就会创建一个vueComponent实例对象&#xff0c; 所以为了避免组件在使用过程中data对象中的值混乱 组件中的data要写成函数&#xff0c; 使得每次创建的组件实例对象都可以返回一…

批量爬虫采集大数据的技巧和策略分享

目录 1. 使用多线程或异步编程&#xff1a; 2. 设置适当的请求频率&#xff1a; 3. 使用代理服务器&#xff1a; 4. 处理异常和错误&#xff1a; 5. 监控和管理任务队列&#xff1a; 6. 数据存储和处理&#xff1a; 7. 随机化请求参数和头信息&#xff1a; 8. 定时任务…

前端组件库造轮子——Input组件开发教程

前端组件库造轮子——Input组件开发教程 前言 本系列旨在记录前端组件库开发经验&#xff0c;我们的组件库项目目前已在Github开源&#xff0c;下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验&#xff0c;开源…

大数据风控介绍

众所周知&#xff0c;金融是数据化程度最高的行业之一&#xff0c;也是人工智能和大数据技术重要的应用领域。随着大数据收集、存储、分析和模型技术日益成熟&#xff0c;大数据技术逐渐应用到金融风控的各个环节。个推作为专业的数据智能服务商&#xff0c;拥有海量数据资源&a…

3D姿态相关的损失函数

loss_mpjpe: 计算预测3D关键点与真值之间的平均距离误差(MPJPE)。 loss_n_mpjpe: 计算去除尺度后预测3D关键点误差(N-MPJPE),评估结构误差。 loss_velocity: 计算3D关键点的速度/移动的误差,评估运动的平滑程度。 loss_limb_var: 计算肢体长度的方差,引导生成合理的肢体长度…

【C++】C++ 引用详解 ⑤ ( 函数 “ 引用类型返回值 “ 当左值被赋值 )

文章目录 一、函数返回值不能是 " 局部变量 " 的引用或指针1、函数返回值常用用法2、分析函数 " 普通返回值 " 做左值的情况3、分析函数 " 引用返回值 " 做左值的情况 函数返回值 能作为 左值 , 是很重要的概念 , 这是实现 " 链式编程 &quo…

改进YOLO系列:10.添加NAMAttention注意力机制

添加NAMAttention注意力机制 1. NAMAttention注意力机制论文2. NAMAttention注意力机制原理3. NAMAttention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. NAMAttention注意力机制论文 论文题目:NAM: Normalization-based Attention Module 论文…

【雷达】接收和去噪L波段雷达接收到的信号研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

空时自适应处理用于机载雷达——机载阵列雷达信号环境(Matla代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Neo4j实现表字段级血缘关系

需求背景 需要在前端页面展示当前表字段的所有上下游血缘关系&#xff0c;以进一步做数据诊断治理。大致效果图如下&#xff1a; 首先这里解释什么是表字段血缘关系&#xff0c;SQL 示例&#xff1a; CREATE TABLE IF NOT EXISTS table_b AS SELECT order_id, order_status F…

【Mac】编译Spring 源码和Idea导入

今天我们开始Spring源码的阅读之旅。阅读Spring的源码的第一步当然是编译Spring源码。首先我们要去GitHub上将spring源码给clone下来。 笔者编译环境如下&#xff1a; Spring版本&#xff1a;5.28 https://github.com/spring-projects/spring-framework/tree/v5.2.8.RELEASE …

JavaScript——为什么静态方法不能调用非静态方法

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

TypeScript三种特殊类型

1.any类型 说明&#xff1a;any类型代表着可以赋值任意类型 let nickname:any"王二"nickname15nicknametruenicknameundefinednicknamenullnickname{}2.unknown类型 说明&#xff1a;类似any类型&#xff1b;只是不能赋值到其它类型上&#xff1b;除了any和known。…

Promise.all和promise.race的应用场景举例

Promise.all( ).then( )适用于处理多个异步任务&#xff0c;且所有的异步任务都得到结果时的情况。 <template><div class"box"><el-button type"primary" plain click"clickFn">点开弹出框</el-button></div> &…

CSS笔记

介绍 CSS导入方式 三种方法都将文字设置成了红色 CSS选择器 元素选择器 id选择器 图中div将颜色控制为红色&#xff0c;#name将颜色控制为蓝色&#xff0c;谁控制的范围最小&#xff0c;谁就生效&#xff0c;所以第二个div是蓝色的。id属性值要唯一&#xff0c;否则报错。 clas…

汤普森采样(Thompson sampling): 理论支持

目录 一、UCB与TS算法数学原理1、Upper Confidence Bounds 数学原理2、Thompson sampling 数学原理a、TS 基本数据原理1. beta 分布2. 共轭分布与共轭先验3. 采样的编程实现 b、TS 算法流程1. TS算法基础版本2. Batched Thompson Sampling 二、UCB与TS算法的优缺点1、TS算法的优…

[管理与领导-49]:IT基层管理者 - 8项核心技能 - 4 - 团队激励

目录 前言&#xff1a; 一、什么是团队激励 二、为什么需要激励 三、激励的误区 3.1 常见误区 3.2 以下是一些常见的激励错误做法&#xff1a; 四、如何正确地激励 五、关于激励的一些理念 六、常见障碍 前言&#xff1a; 管理者存在的价值就是制定目标&#xff0c;即…