软考算法——线性表、栈和队列、串、数组、矩阵和广义表

软考算法(一)

线性表

定义

线性表是具有相同数据类型 的n(n>=0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。若用L命名线性表,则一般表示为: L = ( a 1 , a 2 , a 3 , . . . , a i , a i + 1 , . . . , a n ) L = (a_1,a_2,a_3,...,a_i,a_i+_1,...,a_n) L=(a1,a2,a3,...,ai,ai+1,...,an)

  • a~i~是线性表中"第i个"元素线性表中的位序
  • a~1~是表头元素;a~n~是表尾元素
  • 除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继。

顺序表

单链表

循环链表

双向链表

性能分析

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

线性表插入删除操作

  • 顺序存储
    插入元素前一要移动元素以挪出空的存储单元,然后再插入元素。删除元素同样需要移动元素,以填充被删除元素的存储单元
  • 链式存储
    ①单链表删除节点:

当删除a2节点时,首先我们要引入一个q指针,q指针指向我们的a2节点(为了不丢掉a2节点中存储的数据),再用前一个节点a1指针域中的指针指向a2节点的下一个节点a3,这样就达到了一组删除操作。

②单链表插入节点

在a1和a2之间进行插入操作,引入一个s节点,指向要插入的x节点,接下来要先将x节点指针域中的指针指向a2节点,然后再将a1指针域中的指针指向下一个节点x,如果先将a1指针指向要插入的x节点,那么原本a1后面的a2节点等的数据就会损失。所以一定是先执行将x节点指针域中的指针指向a2节点。

③双向链表删除节点

引入p指针指向即将要进行删除的a2节点,然后用a1节点的后指针指向a2的下一个节点a3完,然后再用a3节点的前指针指向a1,完成连接

④双向链表插入节点

插入一个节点x,还是要引入一个指针q指向即将要插入的节点x,要先进行后面的连接,让x的next指针指向下一个节点a2,再把a2节点的前指针指回x节点,先连后面再连前面,和单链表的插入操作相同

栈和队列

线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。若用L命名线性表,则一般表示为:
L = ( a 1 , a 2 , . . . , a i , a i + 1 , . . . , a n ) L=(a1,a2,...,ai,ai+1,...,an) L=(a1,a2,...,ai,ai+1,...,an)

(Stack )是只允许在一端进行插入或删除操作的线性表。

队列

队列 是一种先进先出(FIFO)的线性表,它只允许在表的一端插入元素,而在表的另一端删除元素。在队列中,允许插入元素的一端称为队尾(Rear),允许删除元素的一端称为队头(Front)。

循环队列

循环队列 是指将它的存储空间进行连接,让队列变成了一个环。循环队列有两个指针,头指针head和尾指针tail,往右插入数据时,tail不断的往后调,在删除数据时,head不断往后调。

循环队列队空条件:head=tail
循环队列队满条件:(tail+1)%size=head

串、数组、矩阵和广义表

是仅由字符构成的有限序列,是取值范围受限的线性表。一般记为S = 'a1 a2 ~~~ an',其中S是串名,a1 a2 an是串值。

  • 空串:长度为0的串,空串不包含任何字符。
  • 空格串:由一个或多个空格组成的串。
  • 子串 :由串中任意长度的连续字符构成的序列。含有子串的串称为主串。子串在主串中的位置指子串首次出现时,该子串的第一个字符在主串中的位置。空串是任意串的子串。
  • 串相等:指两个串长度相等且对应位置上的字符也相同。
  • 串比较:两个穿比较大小时以字符的ASCII码值作为依据。比较操作从两个串的第一个字符开始进行,字符的ASCII码值大者所在的串为大;若其中一个串先结束,则以串长较大者为大。

串的基本操作

  • 赋值操作StrAssign(&T,chars):生成一个其值等于chars的串T。这通常涉及为串分配内存,并将chars的内容复制到新串中。
  • 连接操作Concat(s,t):将串t接续在串s的尾部,形成一个新串。
  • 求串长StrLength(s):返回串s的长度。
  • 串比较StrCompare(s,t):比较两个串的大小。
  • 求子串SubString(,start,len):返回串s中从start开始的、长度为len的字符序列。

串的存储结构

(1)串的顺序存储:定长存储结构

(2)串的链式存储:块链

子串的定位操作通常称为串的模式匹配,它是各种串处理系统中最重要的运算之一。子串也称为模式串。

数组

数组是一个固定长度的存储相同数据类型的数据结构,数组中的元素被存储在一段连续的内存空间中。

数组的存储地址计算

  • 一维数组a[n]
    a [ i ] 的存储地址为: a + i ∗ l e n a[i]的存储地址为:a+i*len a[i]的存储地址为:a+i∗len
  • 二维数组a[m][n]
    a [ i ] [ j ] 的存储地址(按行存储)为: a + ( i ∗ n + j ) ∗ l e n a[i][j]的存储地址(按行存储)为:a+(i*n+j)*len a[i][j]的存储地址(按行存储)为:a+(i∗n+j)∗len
    a [ i ] [ j ] 的存储地址(按列存储)为: a + ( j ∗ m + i ) ∗ l e n a[i][j]的存储地址(按列存储)为:a+(j*m+i)*len a[i][j]的存储地址(按列存储)为:a+(j∗m+i)∗len

例:已知5行5列的二维数组a中的各元素占两个字节,求元素a[2][3]按行优先存储的存储地址
由题意可知:m = 5,n = 5, len = 2,按行优先存储,那么a[2][3]的存储地址为:a+(2 5+3)2=a+26

矩阵------稀疏矩阵

稀疏矩阵是矩阵中的一种特殊类型。在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵。与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。通常认为,当矩阵中非零元素的总数比上矩阵所有元素总数的值小于等于0.05时,该矩阵即可被视为稀疏矩阵,该比值也称为这个矩阵的稠密度。

上三角矩阵

在矩阵中下标分别为i和j的元素,对应的一维数组的下标计算公式为:(2n-i+1)*i/2+j

下三角矩阵

在矩阵中下标分别为i和j的元素,对应的一维数组的下标计算公式为:(i+1)*i/2+j

广义表

广义表是n个表元素组成的有限序列,是线性表的推广。

通常用递归的形式进行定义,记做:LS=( a 0 a_{0} a0, a 1 a_{1} a1,..., a n a_{n} an)。
注:其中LS是表名, a i a_{i} ai是表元素,它可以是表(称做子表),也可以是数据元素(称为原子)。其中n是广义表的长度(也就是最外层包含的元素个数),n = 0的广义表为空表;而递归定义的重数就是广义表的深度,直观的说,就是定义中所含括号的重数(原子的深度为0,空表的深度为1)
基本运算:取表头head(Ls)和取表尾tail(Ls)。
若有 L S 1 = ( a , ( b , c ) , ( d , e ) ) ,则 h e a d ( L S 1 ) = a t a i l ( L S 1 ) = ( ( b , c ) , ( d , e ) ) 若有LS1=(a,(b,c),(d,e)),则\\head(LS1)=a\\tail(LS1)=((b,c),(d,e)) 若有LS1=(a,(b,c),(d,e)),则head(LS1)=atail(LS1)=((b,c),(d,e))

ps:如果要将LS1中的b元素取出,则该怎么操作

基本操作有取表头和取表尾,而表中的元素也可以看做是广义表,那么我们先取一次表尾,得到子表((b,c),(d,e)),再取一次表头,得到它的子表(b,c),然后再取一次表头得到我们想要的元素b,即:head(head(tail(LS1))) 这样一个三层操作。

ps:如果记不住公式,可用代入法

相关推荐
IronmanJay1 小时前
【LeetCode每日一题】——862.和至少为 K 的最短子数组
数据结构·算法·leetcode·前缀和·双端队列·1024程序员节·和至少为 k 的最短子数组
加载中loading...2 小时前
Linux线程安全(二)条件变量实现线程同步
linux·运维·服务器·c语言·1024程序员节
Wx120不知道取啥名2 小时前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
biomooc3 小时前
R语言 | paletteer包:拥有2100多个调色板!
r语言·数据可视化·1024程序员节
Hello.Reader3 小时前
FFmpeg 深度教程音视频处理的终极工具
ffmpeg·1024程序员节
Y.O.U..4 小时前
STL学习-容器适配器
开发语言·c++·学习·stl·1024程序员节
就爱敲代码4 小时前
怎么理解ES6 Proxy
1024程序员节
憧憬一下4 小时前
input子系统的框架和重要数据结构详解
arm开发·嵌入式·c/c++·1024程序员节·linux驱动开发
三日看尽长安花4 小时前
【Tableau】
1024程序员节
sswithyou5 小时前
Linux的调度算法
1024程序员节