软考:软件设计师 — 13.数据结构

十三. 数据结构

数据结构部分也可参考文章:Java数据结构知识点 — 5种常见数据结构 

1. 线性结构

(1)线性表

顺序表

线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。数组的内存是连续、静态分配的,即在使用数组之前需要分配固定大小的空间。

  • 读操作:直接找到对应位置,时间复杂度为 O(1)。
  • 查询操作:最少查 1 个,最多查 n 个,平均查 \frac{n+1}{2} 个。
  • 插入操作:最少后移 0 个(插在末尾),最多后移 n 个(插在开头),平均后移 \frac{n+1}{2} 个。
  • 删除操作:最少前移 0 个(删末尾),最多前移 n-1 个(删开头),平均前移 \frac{n-1}{2} 个。

链表

线性表的链式存储是用通过指针链接起来的结点来存储数据元素。链表的内存是不连续的,前一个元素存储地址的下一个地址中存储的不一定是下一个元素。链表通过一个指向下一个元素地址的引用将链表中的所有元素串起来。

结点的基本结构:

链表的每个结点实际上是一个结构体变量,有若干成员组成,包括数据部分和指针变量。

struct node{int data;          // 结点的数据域struct node *link; // 结点的指针域
}

链表的基本结构:

  • 尾结点:最后一个有效结点。
  • 首结点:第一个有效结点。
  • 头结点:第一个有效结点之前的那个结点,存放链表首地址。
  • 头指针:指向头结点的指针变量。
  • 尾指针:指向尾结点的指针变量。 

 链表的特点:

  • n 个结点离散分布,彼此通过指针相联系。
  • 除头结点和尾结点外,每个结点只有一个前驱结点和一个后继结点。头结点没有前驱结点,尾结点没有后继结点。
  • 头结点并不存放有效数据,只存放链表首地址。其头结点的数据类型和首结点类型一样。
  • 加头结点的目的是方便对链表的操作,比如在链表头部进行结点的删除、插入。

链表的分类:

根据链表中指针域的设置方式,链表可分为:单链表、循环链表、双向链表。

单链表的插入与删除操作:

p 所指结点后插入新元素结点(s 所指结点)

① s -> link = p -> link;

② p -> link = s; 

删除 p 所指结点的后继结点

① q = p -> link;

② p -> link = p -> link -> link;

③ free(q);

删除 p 所指结点

①  p -> data = p -> link -> data;

② q = p -> link;

③ p -> link = p -> link -> link;

④ free(q);

这种方式比较灵活,是将 p 结点的数值域用下一个结点的数值域覆盖,这样就不存在 p 结点了,然后删除下一个结点即可,也相当于变相删除了 p 结点。

双向链表的插入与删除操作:

插入 q 所指向的结点

① s -> front = p -> front;

② p -> front -> link = s;

③ s -> link = p;

④ p -> front = s;

删除结点 p 指向的结点

① p -> front -> link = p -> link;

② p -> link -> front = p -> front;

③ free(p); 

顺序存储与链式存储对比

性能类别具体项目顺序存储链式存储
空间性能存储密度=1,更优<1
容量分配事先确定动态改变,更优
时间性能查找O(n)O(n)
O(1),更优O(n),最好情况为 1,最坏情况为 n
插入O(n),最好情况为 0,最坏情况为 nO(1),更优
删除O(n)O(1),更优

例题:

设有一个包含 n 个元素的有序线性表。在等概率情况下删除其中一个元素,若采用顺序存储结构,则平均需要移动()个元素;若采用单链表存储,则平均需要移动()个元素。

A.1  B.(n-1)/2  C.longn  D.n

A.0  B.1  C.(n-1)/2  D.n/2

解析:

删除元素,顺序表平均前移 \frac{n-1}{2} 个元素,链式表不需要移动元素,只需删除结点指针即可,因此选 BA。

(2)队列与栈

栈按照 “后进先出” 的原则操作。在栈顶进行入栈和出栈。

队列

队列按照 “先进先出” 的原则操作。在队尾入队,队头出队。常与循环单链表结合使用,不需要遍历。

一种比较特殊的队列是循环队列 

  • 队空条件:head = tail
  • 队满条件:(tail + 1)% size = head
  • 队列长度:(tail - head + size)% size

tail 指向最后一个元素的后一个位置,因此实际是空余一个位置。

例题1:

对于一个长度为 n(n>1) 且元素互异的序列,令其所有元素依次通过一个初始为空的栈后,再通过一个初始为空的队列。假设队列和栈的容量都足够大,且只要栈非空就可以进行出栈操作,只要队列非空就可以进行出队操作,以下叙述中,正确的是()。

A.出队序列和出栈序列一定互为逆序。

B.出队序列和出栈序列一定相同。

C.入栈序列和入队序列一定相同。

D.入栈序列和入队序列一定互为逆序。

解析1:

由题干可知,出栈序列和入队序列一定是相同的,因为出栈后必入队,只要栈和队列都非空,而入队和出队次序相同,队列先进先出,所以出队序列和出栈序列相同。B 正确,A 错误。而入栈序列是未知的,因为可能存在某个元素 a 先进栈然后出栈,然后又有两个元素 b c 依次进栈,此时出栈的顺序就变成了 c b,所以入队序列也就不相同也不互逆,因此 CD 错误。

例题2:

队列的特点是先进先出,若用循环单链表表示队列,则()。

A.入队列和出队列操作都不需要遍历链表。

B.入队列和出队列操作都需要遍历链表。

C.入队列操作需要遍历链表而出队列不需要。

D.入队列操作不需要遍历链表而出队列需要。

解析2:

入队在队尾,出队在对头,所以不需要遍历链表。选项 A 正确。

例题3:

若元素以 a,b,c,d,e 的顺序进入一个初始为空的栈中,每个元素进栈、出栈各 1 次,要求出栈的第一个元素为 d,则合法的出栈序列共有()种。

A.4  B.5  C.6  D.24

解析3:

出栈的第一个元素要求为 d,那么在 d 前面一定是 c,b,a,因为栈是后进先出,e 还没有进栈。d 第一个出栈,然后看剩余的元素 c b a 和 e 的排列方式,e 可以在 c 之前,也可以在 c b 之间,或 b a 之间,或 a 之后,因此出栈序列共 4 种。选 A。

例题4:

双端队列是指在队列的两个端口都可以加入和删除元素,如下图所示。现在要求元素进队和出队都必须在同一端口,即从 A 端进队的元素必须从 A 端出、从 B 端进队的元素必须从 B 端出,则对于 4 个元素的序列 a、b、c、d,若要求前两个元素(a、b)从 A 端口按次序全部进入队列,后两个元素(c、d)从 B 端口按次序全部进入队列,则不可能得到的出队序列是()。

A.d、a、b、c  B.d、c、b、a  C.b、a、d、c  D.b、d、c、a

解析4:

可以想象成有一条线将队列从中间隔开,一端是 A,一端是 B,而每端是栈,a、b 元素进入 A 端后,b 元素不出来,a 元素也无法出来,同理,B 端也是,d 元素不出来,c 元素也出不来。所以只有 A 选项错误,d 元素先出,然后要么下一个元素要么是 c 出来,要么是 b 出来,而 a 无法出来。 

(3)串

串是仅有字符构成的有限序列,是一种线性表。一般记为 S = 'a_{1}a_{2}\cdots a_{n}',其中,S 是串名,单引号括起来的字符序列是串值。

串的几个基本概念:

  • 空串:长度为零,不包含任何字符。
  • 空格串:由一个或多个空格组成的串。虽然空格是一个空白字符,但它也是一个字符,在计算串长度时要将其计算在内。
  • 字串:由串中任意长度的连续字符构成的序列称为子串(2 的 n 次方,n 为单个字符个数)。含有子串的串称为主串。子串在主串中的位置是指子串首次出现时,该子串的第一个字符在主串中的位置。空串是任意串的子串。
  • 子序列:一个串的子序列是将这个串中的一些字符提取出来得到一个新串,并且不改变它们的相对位置关系。也就是说,假设一个串是 abbc,那么 ab、ac都是它的子序列。
  • 串比较:两个串比较大小时以字符的 ASCII 码值作为依据。实质上,比较操作从两个的第一个字符开始进行,字符的码值大者所在的串为大;若其中一个串先结束,则以串长较大者为大。
  • 串相等:指两个串长度相等且对应序号的字符也相同。

串的基本操作:

  • 赋值操作 StrAssign(s,t):将串 s 的值赋给串 t。
  • 连接操作 Concat(s,t):将串 t 接续在串 s 的尾部,形成一个新的串。
  • 求串长 StrLength(s):返回串 s 的长度。
  • 串比较 StrCompare(s,t):比较两个串的大小。返回值 -1、0 和 1 分别表示 s<t、s=t 和 s>t 三种情况。
  • 求子串 SubString(s,start,len):返回串 S 中从 start 开始的、长度为 len 的字符序列。

串的存储:

  • 顺序存储:用一组地址连续的存储单元来存储串值的字符序列。
  • 链式存储:用链表存储串中的字符,,每个结点中可以存储一个字符,也可以存储多个。

串的模式匹配:

子串的定位操作通常称为串的模式匹配。(子串也称为模式串)

  • 朴素的模式匹配算法(布鲁特-福斯算法):其基本思想是从主串的第一个字符起与模式串的第一个字符比较,若相等,则继续逐一对字符进行后续的比较,否则从主串第二个字符起与模式串的第一个字符重新比较,直到模式串中每个字符依次与主串中一个连续的字符序列相等时为止,此时称为匹配成功。如果不能在主串中找到与模式串相同的子串,则匹配失败。
  • 改进的模式匹配算法(KMP算法):其改进之处在于,每当匹配过程中出现相比较的字符不相等时,不需要回退到主串的字符位置指针,而是利用已经得到的部分匹配结果将模式串向右滑动尽可能远的距离,再继续进行比较。

在 KMP 算法中,依据模式串的 next 函数值实现子串的滑动。若令 next[j] = k,则 next[j] 表示当模式串中的 p_{j} 与主串中相应字符不相等时,令模式串的 p_{next[j]]} 与主串的相应字符进行比较。(j = next[j])

next 函数定义如下:

需要掌握 next 函数值的求取,并且可能出题老师给出的 next 函数定义不同,但本质计算过程相同。其中,第二条是指有多个 k 值时,选择最大的那个。

例题1:

在字符串的 KMP 模式匹配算法中,需先求解模式串的 next 函数值,其定义如上图所示,j 表示模式串中字符的序号(从 1 开始)。若模式串 p 为 'abaac',则其 next 函数值为()。

A.01234  B.01122  C.01211  D.01111

解析1:

j12345
模式串abaac
next[j]01122

当 j = 1 时,next[j] = 0;当 j = 2 时,即 1<k<2,不存在整数 k ,因此是其它情况,next[j] = 1;当 j = 3 时,即 1<k<3,因此 k = 2,此时需要判断表达式 'p1p2…pk-1' = 'pj-k+1 pj-k+2…pj-1' 是否满足条件,即 p1p2…pk-1 = p1 = a,pj-k+1pj-k+2…pj-1 = p2 = b,a ≠ b,所以不满足条件,是其它情况,next[j] = 1;当 j = 4 时,即 1<k<4,因此 k = 2 或 3,当 k = 2 时,表达式为 p1 = p3,为真(a = a),当 k = 3 时,表达式为 p1p2 = p2p3,为假(ab ≠ ba),所以当 j = 4 时,k = 2;同理,继续推断 j = 5,即 1<k<5,k = 2 或 3 或 4,当 k = 2 时,表达式为 p1 = p4,满足条件,当 k = 3 时,表达式为 p1p2 = p3p4,为假,不满足条件,当 k = 4 时,表达式为 p1p2p3 = p2p3p4,为假,不满足条件,因此 next[j] 的值为 2。所以 next 函数值为 01122,选 B。

例题2:

设 S 是一个长度为 n 的非空字符串,其中的字符各不相同,则其互异的非平凡子串(非空且不同于 S 本身)个数为()。

A.2n-1  B.n^{2}  C.n(n+1)/2  D.(n+2)(n-1)/2

解析2:

可以通过举例判断,单个字符 a 的非平凡子串个数是 0,非空且不同于本身,也就是 n = 1,可以直接判断出只有 D 项,在 n = 1 时为 0,因此选 D。

后续会持续更新整理。

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

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

相关文章

并行计算模型

像其他专业行话一样&#xff0c;并行计算也有自己的行话。行话就像个大坑&#xff0c;坑中的人需要在其中浸淫很久&#xff0c;才能逐渐适应其语境&#xff0c;然而很多行话的使用常常是草率与不精确的。有时候把鬼都听不懂的行话理解了&#xff0c;再跟别人说鬼话&#xff0c;…

【MySQL 06】表的约束

文章目录 &#x1f308; 一、约束的概念&#x1f308; 二、空属性约束⭐ 1. 空值无法参与运算⭐ 2. 设置非空属性 &#x1f308; 三、默认值约束⭐ 1. 默认值使用案例⭐ 2. 同时设置 not null 和 default &#x1f308; 四、列描述约束&#x1f308; 五、zerofill 补零约束&…

校园外卖平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;菜品信息管理&#xff0c;菜品分类管理&#xff0c;购买菜品管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&a…

【python报错已解决】`IndexError: list index out of range`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一&#xff1a;检查索引范围2.2 方法二…

Java - IDEA开发

使用IDEA开发Java程序步骤&#xff1a; 创建工程 Project&#xff1b;创建模块 Module&#xff1b;创建包 Package&#xff1b;创建类&#xff1b;编写代码&#xff1b; 如何查看JDK版本 Package介绍: package是将项目中的各种文件,比如源代码、编译生成的字节码、配置文件、…

哈希表 - 三数之和

15. 三数之和 方法一&#xff1a;排序双指针 /*** param {number[]} nums* return {number[][]}*/ var threeSum function(nums) {const res [], len nums.length;// 将数组排序nums.sort((a, b) > a - b)for (let i 0; i < len; i) {let l i 1, r len - 1, iNum…

宝塔面板实现定时任务删除 logs文件 加条件删除 只删除一个月前的日志

我们在开发中难免用到了日志功能&#xff0c;随着日志越来越多导致占用我们的内存 下面是一个简单的 使用宝塔面板里面的定时任务来实现删除日志案例 第一步 首先我的日志文件目录 都在log文件夹里面&#xff0c; 每个月生成一个日志文件夹 文件夹命名是年月来命名的 第二…

Java面试八股之什么是AMQP协议

什么是AMQP协议 AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff09;是一个开放标准的应用层协议&#xff0c;旨在为消息中间件提供一种统一的、标准的通信方式。它允许消息在分布式系统中的应用程序之间进行可靠的、异步的传递。AMQ…

【云原生】Pass容器研发基础——汇总篇

云原生基础汇总 系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了云计算学习的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;每个知识点的修正和深入主要参考各平台大佬的文章&#xff0c…

Linux2.6内核进程调度队列详细讲解

上图是 Linux2.6 内核中进程队列的数据结构&#xff0c;之间关系也已经给大家画出来&#xff0c;方便大家理解。 一个 CPU 拥有一个 runqueue。 Linux真正的调度方式是通过runqueue进行调度的&#xff0c;我们知道进程的优先级范围是根据nice值确定的&#xff0c;而nice值的范围…

Raspberry Pi Pico 2 上实现:实时机器学习(ML)音频噪音抑制功能

Arm 公司的首席软件工程师 Sandeep Mistry 为我们展示了一种全新的巧妙方法&#xff1a; 在 Raspberry Pi Pico 2 上如何将音频噪音抑制应用于麦克风输入。 机器学习&#xff08;ML&#xff09;技术彻底改变了许多软件应用程序的开发方式。应用程序开发人员现在可以为所需系统整…

【单片机】51单片机入门教程(二):定时器的模式详解与中断应用实例

文章目录 51单片机定时器教程:模式详解与中断应用实例1. 介绍2. 51单片机定时器/计数器概述3. 定时器控制寄存器与中断入口4. 模式0:13位定时器/计数器5. 模式1:16位定时器/计数器6. 模式2:8位自动重装载定时器/计数器7. 模式3:分割两个独立的8位定时器/计数器8. 总结51单…

可视化基础的设计四大原则

一个好的数据可视化设计可以帮助观众迅速理解数据背后的意义。然而&#xff0c;如何确保我们的可视化设计既美观又简单易懂呢&#xff1f;本文将介绍四大设计原则——亲密原则、对比原则、对齐原则和重复原则。 1、 亲密原则&#xff08;Proximity&#xff09; 定义与应用&am…

JVM运行时数据区之虚拟机栈

【1】概述 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff09;&#xff0c;早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个的栈帧&#xff08;Stack Frame&#xff09;&#xff0c;对应着一次次的Java方法调用。 栈是运行…

Leetcode JAVA刷刷站(20)有效的括号

一、题目概述 二、思路方向 在Java中&#xff0c;要判断一个仅包含括号&#xff08;(, ), {, }, [, ]&#xff09;的字符串是否有效&#xff0c;你可以使用栈&#xff08;Stack&#xff09;数据结构来实现。栈是一种后进先出&#xff08;LIFO, Last In First Out&#xff09;的…

达梦数据库 逻辑备份还原

达梦的逻辑备份还原 1.背景2.要求3.实验步骤3.1 相关术语3.2 dexp逻辑导出3.2.1 使用dexp工具3.2.2 dexp相关参数含义3.2.3 四种级别导出3.2.3.1 FULL3.2.3.2 OWNER3.2.3.3 SCHEMAS3.2.3.4 TABLES 3.2.4 使用范例3.2.4.1 环境准备3.2.4.2 dexp逻辑导出 3.3 dimp逻辑导入3.3.1 使…

AI大模型赋能游戏:更智能、更个性化的NPC

参考论文&#xff1a;https://arxiv.org/abs/2403.10249 在传统游戏中&#xff0c;NPC&#xff08;非玩家角色&#xff09;的行为往往是预先设定好的&#xff0c;缺乏灵活性和变化性。然而&#xff0c;基于大模型的NPC可以利用其强大的推理和学习能力&#xff0c;实时生成对话…

汇编语言指令 jmp:jmp short、jmp near ptr、jmp far ptr

引言&#xff1a; 在8086CPU中&#xff0c;可以修改IP&#xff08;Instruction Pointer &#xff0c;指令指针寄存器&#xff09;或同时修改CS&#xff08;Code Segment&#xff0c;代码段寄存器&#xff09;和IP的指令称为转移指令&#xff0c;更通俗的说&#xff0c;转移指令…

React H5设置企业级v6版本路由的配置

路由配置是项目开发的必要一环&#xff0c;尤其是目前流行SPA&#xff0c;下面看看如何使用v6版本路由进行合理的H5路由配置 一、基本页面结构&#xff08;目录根据开发要求建&#xff0c;下面仅用于展示配置路由&#xff09; 二、具体文件实现 1. index.tsx import React f…

用python的manim库实现表格格式操作【table 下】

1.Table 是 Manim 中用于创建一个包含文本或其他 数学符号的表格的类 Table 是 Manim 中用于创建一个包含文本或其他 数学符号的表格的类它能够帮助你在场景中清晰地展示数据或信息。 参数解释 table: 一个二维数组或列表&#xff0c;表示表格中的内容。每个子列表代表表格的…