title: 数据结构笔记 categories: - 数据结构 tags: - 笔记 toc: true
第二、三、四章 线性表
字符串:线性表特例
多维数组:线性表推广(严格不是)
线性表(表):具有相同类型的数据元素的有限序列
-> 将元素类型限制为字符:字符串(串):零个或多个字符组成的有限序列
串长:串中所包含的字符个数
空串:长度为 0 的串
子串:串中任意个连续的字符组成的子序列(包含空串) 主串:包含子串的串 子串的位置:子串的第一个字符在主串中的序号
串的存储结构
字符串通常采用顺序存储,即用数组存储
模式匹配
-> BF算法
模式匹配:在主串 S 中寻找子串 T 的过程,T 也称为模式
如果匹配成功,返回 T 在 S 中的位置;否则返回 0
模式匹配问题有什么特点?
(1) 算法的一次执行时间:问题规模通常很大,常常在大量信息中进行匹配
(2) 算法改进所取得的积累效益:模式匹配操作经常被调用,执行频率高
数组的存储结构
如何存储(多维)数组呢?
数组没有插入和删除操作,所以,不用预留空间,适合采用顺序存储
按行优先:先存储行号较小的元素,行号相同者先存储列号较小的元素
按列优先:先存储列号较小的元素,列号相同者先存储行号较小的元素
-> KMP算法
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
char[i] | a | b | a | b | a | b | c |
next | -1 | 0 | 0 | 1 | 2 | 3 | 4 |
nextval | -1 | 0 | -1 | 0 | -1 | 0 | 4 |
一、过程: 求next值: 1.两个固定值:char[0]next=-1; char[1]next=0(一个,没有匹配的,长度为0) 2.开始求:char[2]匹配出错,前面a!=b(两组字符不同),故next=0(重头开始) char[3]匹配出错,前面有aba, a(char[3]前面的a)和a(匹配必从第一个开始)相同,字符a长度为1,故next=1 char[4]匹配出错,前面有abab,ab和ab相同,长度为2,故next=2 char[5]匹配出错,前面有ababa,aba和aba(123和345)相同,长度为3,故next=3 char[6]匹配出错,前面有ababab,abab和abab(1234和3456)相同,长度为4,故next=4 求nextval值: 1.一个固定值:char[0]nextval=-1 2.开始求:char[1]next=0(char[0]=a), a!=b,所以nextval=char[1]next char[2]next=0(char[0]=a),a==a,所以nextval=char[0]_nextval 同理可得……
二、总结: 求next的值: 看当前字符的前面的一组字符是否有相似的一组字符(开头开始)与之相同,取其最大长度作为next的值 求nextval值(修正值): 当前字符的next值(索引值)所指向的字符是否和当前字符相同:相同则修正值为当前字符的next值所指向的字符的修正值;不同则去当前字符的next值
三、例子再来一个:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
a | b | c | a | b | c | a | b | a | a | |
next | -1 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 1 |
nextval | -1 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 5 | 1 |
求next值:next0=-1,next1=0 a!=b,next2=0; abc不可能(ab!=bc),next3=0; 0==3,next4=1; 01==34,next5=2;012==345,next6=3; abca==abca(1234==3456),next7=4; 01234==34567,next8=5 1==8,next9=1 求nextval值:nextval0=-1 b!=char[next1]=a, nextval=next1=0 c!=char[next2]=a, nextval=next2=0 a==char[next3]=a,nextval=nextval0=-1 同理可得……
这个思路也可以:
[(7条消息) KMP算法中计算next值和nextval的值threecat.up的博客-CSDN博客kmp算法next修正值计算方法KMP算法中计算next值和nextval的值_threecat.up的博客-CSDN博客_nextval值怎么求](
特殊矩阵的压缩存储
什么是特殊矩阵?
特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律
特殊矩阵如何压缩存储?
为值相同的元素分配一个存储空间
特殊矩阵压缩存储后有什么要求吗?
保证随机存取,即在O(1)时间内寻址
-> 对称矩阵的压缩存储
如何压缩存储对称矩阵呢? 只存储下三角部分的元素
aij 在一维数组中的下标 k = i×(i-1)/2+ j-1
对称矩阵压缩存储后的寻址方法
对于下三角中的元素aij(i ≥ j):k=i×(i-1)/2+j -1
对于上三角中的元素aij(i<j),因为aij=aji,则 k=j×(j-1)/2+i -1
-> 三角矩阵的压缩存储
如何压缩存储三角矩阵呢?
下(上)三角部分的元素;相同的常数只存储一个
下三角矩阵压缩存储后的寻址方法
对于下三角中的元素aij(i ≥ j):k=i×(i -1)/2 + j-1
对于上三角中的元素aij(i<j):k=n×(n + 1)/2
-> 对角矩阵的压缩存储
对角矩阵:所有非零元素都集中在以主对角线为中心的带状区域中,所有其他元素都为零
稀疏矩阵的压缩存储
什么是稀疏矩阵?
稀疏矩阵:矩阵中有很多零元素,并且分布没有规律
稀疏矩阵如何压缩存储?
只存储非零元素,零元素不分配存储空间
如何只存储非零元素?
三元组:(行号,列号,非零元素值)
-> 三元组顺序表
三元组表:将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成一个线性表
-> 十字链表
第五章 树和二叉树
树的前序遍历等价于二叉树的前序遍历! 树的后序遍历等价于二叉树的中序遍历!
先访问该结点打标记,再孩子入队列->图结构时,不会造成重复入队 先访问左右孩子入队列,再打标记 ->图结构时会造成重复入队
逻辑关系
线性结构中,数据元素之间具有线性关系,逻辑关系表现为前驱-后继;
树结构中,结点之间具有层次关系,逻辑关系表现为双亲-孩子
图结构中,任意两个顶点之间都可能有关系,逻辑关系表现为邻接
树
树:n个结点(数据元素)的有限集合 ,当 n=0 时,称为空树;任意一棵非空树 T 满足以下条件: (1)有且仅有一个特定的称为根的结点; (2)当 n>1 时,除根结点之外的其余结点被分成 m(m > 0)个互不相交的有限集合 T1,T2,… , Tm,其中每个集合又是一棵树,并称为这个根结点的子树。
*树的定义是采用递归方法
互不相交的具体含义是什么? 结点:结点不能属于多个子树 边:子树之间不能有关系 *互不相交->没有回路->树结构具有层次性
结点的度:结点所拥有的子树的个数
树的度:树中各结点度的最大值 叶子结点:度为 0 的结点,也称为终端结点 分支结点:度不为 0 的结点,也称为非终端结点
*在树结构中,逻辑关系表现为双亲——孩子
路径:结点序列 n1, n2, …, nk 称为一条由 n1 至 nk 的路径,当且仅当满足如下关系:结点 ni 是 ni+1 的双亲(1<=i<k)
路径长度:路径上经过的边的个数
在树结构中,路径是唯一的 祖先、子孙:如果有一条路径从结点 x 到结点 y,则 x 称为 y 的祖先,而 y 称为 x 的子孙
结点所在层数:根结点的层数为 1;对其余结点,若某结点在第 k 层,则其孩子结点在第 k+1 层
树的深度(高度):树中所有结点的最大层数
树的宽度:树中每一层结点个数的最大值
树的遍历
->前序,中序,后序和层序
树的遍历:从根结点出发,按照某种次序访问树中所有结点,并且每个结点仅被访问一次
树的存储结构
->双亲,孩子,孩子兄弟表示法
实现树的存储结构ÿ