此文章已经同步更新到个人博客上,喜欢有侧边栏目录的同学,可以点击下面的链接跳转到个人博客上读阅噢。建议到个人博客读阅,优快云这边更新比较慢,个人博客上,每天都有更新。需要教学视频和真题的,也可以点击下面的个人博客地址,在文末有免费的百度云链接分享。
个人博客地址:http://zwd596257180.gitee.io/blog/2019/04/20/soft_exam/
数据结构与算法基础
线性表
基本数据结构
顺序表
在内存中是顺序存储的。内存划分出来的区域是连续的区块。
链表
在内存中是离散存储的。
-
head:头结点
-
结点:包括数据域和指针域(next 域)
链表的分类
单链表
头结点 head 指向第一个结点的数据域,第一个结点的指针域指向下一个结点的数据域…
注意:单链表的最后一个结点的指针域为空(null)!!! |
循环链表
注意:循环表的最后一个结点的指针域不为空,而是指向了头结点!!! |
双链表
链表的操作
单链表的结点删除
需求:删除 a2 结点
具体操作:将要删除的结点(a2)的前一个结点(a1)的 next 域指向 a2 的后一个的结点(a3)的数据域,然后释放(free)掉 a2 即可。
单链表的结点插入
需求:在 a1 结点后面插入一个新的结点 x
具体操作:将 a1 的 next 域指向 x 的数据域,将 x 的 next 域指向 a2 的数据域即可。
顺序表与链表的比较
性能类别 | 具体项目 | 顺序存储 | 链式存储 |
---|---|---|---|
空间性能 | 存储密度 | =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),更优 |
栈
- 思想:先进后出
队列
线性队列
- 思想:先进先出
循环队列
head:头指针(队头)
tail:尾指针(队尾)
-
当队列中没有存入值的时候,head 指针和 tail 指针指向同一个元素,并且该元素的值是空的!!!
-
当循环队列开始存入值时,head 指针是不动的,tail 指针是后移一个位置。
注意: 循环队列中为了能够区别队空和队满,牺牲了队列的最后一个空间。 判空条件:head = tail 判满条件:head = tail+1 |
树和二叉树
树的一些基本概念
(结合下面的图进行解释)
- 结点的度:结点1与下一层的3个结点相关联,所以结点1的度为3。
- 树的度:所有结点度当中,度数最高的一个,所以如图树的度为3。
- 叶子结点:度为 0 的结点。
- 分支结点:除了叶子节点外,其它都属于分支结点。
- 内部结点:除了根节点和叶子结点外,其它都属于内部结点。
- 父结点
- 子结点
- 兄弟结点
- 层次:如图所示。
树的遍历
前序遍历
访问顺序:先访问根节点再访问子结点。
如上图的前序遍历为:1,2,5,6,7,3,4,8,9,10
后序遍历
访问顺序:先访问子结点再访问跟结点
如上图的后序遍历为:5,6,7,2,3,9,10,8,4,1
层次遍历
访问顺序:从上往下,一层一层访问
如上图的层次遍历为:1,2,3,4,5,6,7,8,9,10
二叉树
注意:二叉树并不是一种特殊的树,而是一种独立的数据结构,有明确的左结点和右结点。 |
完全二叉树的概念:
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
二叉树的重要特性:
-
在二叉树的第 i 层上最多有 2^(i-1) 个结点(i>=1)
-
深度为 k 的二叉树最多有 2^k - 1 个结点(k>=1)
-
对任何一颗二叉树,如果其叶子结点数为 n0,度为 2 的结点数为 n2,则 n0=n2+1
-
下图中的运算符号为向下取整。
二叉树的遍历
前序遍历
- 先访问根结点,接着访问左结点,最后访问右结点。
中序遍历
- 先访问左结点,接着访问根结点,最后访问右结点。
后序遍历
- 先访问左结点,结合访问右结点,最后访问根结点。
树与二叉树的转换
- 加线:在兄弟之间加一连线
- 抹线:对每个结点,除了其左孩子外,去除其与其余孩子之间的关系
- 旋转:以树的根结点为轴心,将整树顺时针转45°
注意:转换后,树和二叉树的前序遍历一样。 |
二叉排序树
左子树的值小于根结点的值,右子树的值大于根结点的值。
在常用的描述二叉排序树的存储结构中,关键字值最大的结点的右指针一定为空。
最优二叉树(哈弗曼树)
- 需要了解的基本概念
树的路径长度:从根结点到某结点的边数
权:人为赋值
带权路径长度:权值乘于边数
树的带权路径长度:所有的叶子结点的带权路径长度相加
例子:由权值为9,2,5,7的4个叶子结点构造一棵哈弗曼树,该树的带权路径长度为(44)。
解析:
构造哈夫曼树的方法是依次从提供的权值中(9,2,5,7)选取两个权值最小(2,5)的最为左右结点,组合成一个新的根节点(2+5=7)也要参与到第二次权值选择中。也就是说,第二次要从(9,7,7)中选取两个最小的权值。
最后生成的树如下图:
例子:若一颗哈夫曼树共有9个顶点,则其叶子节点的个数为(5)。
n0 = n2 +1
9 = n0 + n2
平衡二叉树
基本概念
它或者是一颗空数,或者是一颗这样的树:树中任一结点的左、右子树的深度相差不超过1(即平衡查找树的每个结点的平衡度只能为 -1,0,1 三个值之一)。
平衡树的建立
平衡树调整
LL 型平衡旋转(单向右旋平衡处理)
- 第一种情况:
- 第二种情况
RR 型平衡旋转(单向左旋平衡处理)
LR 型平衡旋转(双向旋转,先左后右)
RL 型平衡旋转(双向旋转,先右后左)
图
图的构成
- 一个图是由两个集合:V和E组成,V是有限的非空顶点集合,E是用顶点对表示的边集合,图G的顶点集和边集分别记为V(G)和E(G),而将图G表示为G=(V,E),也就是说,决定一个图需要知道它的顶点集合与边的集合。
无向图与有向图
- 区别于边是否有箭头。
假设A,B为图中的两个顶点。
无向图的边表示方法:(A,B)
有向图的边表示方法:<A→B>、<B→A>
顶点的度(degree)
-
关联顶点的边数
-
有向图:入度和出度
子图
- 已知图A和图B,如果图B中所有的顶点都是图A中的顶点,图B中的所有边都是图A中的边,则图B是图A的子图。允许两种极端情况:什么都不删;删去所有点和所有线
真子图:同“子图”概念一样,但不允许什么都不删。
完全图
无向图,每对顶点之间都有一条边相连,则称该图为完全图。
有向图,每对顶点之间都有两条有向边相互连接,则称该图为完全图。
路径和回路
- 假设图中的两个顶点A和B,A到B之间经过的边数称为路径。从顶点A出现,最后又回到顶点A,所走过的边组成的称为回路。
连通图和连通分量
无向图:任何两个顶点都有路径到达的图,称为连通图。
有向图:每两个顶点之间都能够有边(此处的边为有向边)到达的图,称为连通图。
连通分量:把连通图给分割出来,每一部分都是该图的连通分量。
邻接矩阵
图的遍历
图的最小生成树
普里姆算法(Prim 算法)
先选取树的第一个顶点(如图点0),再判断所选点到其它点的权值,如果的所选点无法直接到达的点,权值暂时标记为无穷大,然后选取与点0的权值最小的点作为树的第二个顶点。然后再以第二个顶点为基点,判断与其它点的权值大小,循环以上得到第二个顶点的操作,直到生成了树。
克鲁斯卡算法
- 算法思想:依次选取权值最小的边,只要不行成回路即可。
拓扑排序
AOV 网络
我们把用有向边表示活动之间开始的先后关系。
这种有向图称为用顶点表示活动网络,简称AOV网络。
拓扑顺序
入度为0先进行。
上图的拓扑序列有:02143567,01243657,02143657,01243567
关键路径
AOE 网络
在AOV网络中,如果边上的权表示完成该活动所需的时间,则称这样的AOV为AOE网络。
关键路径的几个重要概念
关键路径,就是从源点到终点,路径长度最长的路径。 |
排序算法
各类排序算法时间复杂度和空间复杂度的对比表
哈希算法(Hash)
什么是 Hash 表
Hash 函数的构造方法
处理冲突方法
哈希表的查找
可以查考这个博客学习:https://www.cnblogs.com/zhangbing12304/p/7997980.html
查找算法
编译原理
文法
终结符与非终结符
大写字母为非终结符
小写字母为终结符,不能单独在左边。
例子:
有文法G2[S]为:
- S->Ap
- S->Bq
- A->a
- A->cA
- B->b
- B->dB
则 S,A,B为非终结符,而p,q,a,b,c,d为终结符。
-
VN 表示非终结符集合,即 VN = {S,A,B};
-
VT 表示终结符集合,即 VT = {p,q,a,b,c,d};
-
P 表示生成式,即上面给出的生成式(S->Ap等);
-
S 表示开始符。
文法的类型
0 型文法
设G=(VN,VT,P,S),如果它的每个产生式α→β是这样一种结构:α∈( VN∪VT )且至少含有一个非终结符,而 β∈(VN∪VT),则G是一个0型文法。0型文法也称短语文法。
一个非常重要的理论结果是:0型文法的能力相当于图灵机(Turing)。或者说, 任何0型文语言都是递归可枚举的,反之,递归可枚举集必定是一个0型语言。
0型文法是这几类文法中,限制最少的一个,所以我们在试题中见到的,至少是0型文 法。
1 型文法
1型文法也叫上下文有关文法,此文法对应于线性有界自动机。它是在0型文法的基础上每一个α→β,都有 |β|>=|α|。这里的|β|表示的是β的长度。
例如:
A->B,|α| = 1,而 |β| = 1;
A->Bba,|α| = 1,而 |β| = 3.
注意:虽然要求|β|>=|α|,但有一特例:α→ε也满足1型文法。 如有 A->Ba 则 |β|=2,|α|=1符合1型文法要求。反之,如 aA->a,则不符合1型文法。 |
2 型文法
2型文法也叫上下文无关文法,它对应于下推自动机。2型文法是在1型文法的基础上,再满足:每一个 α→β 都有 α 是非终结符。如A->Ba,符合2型文法要求。
如 Ab->Bab 虽然符合1型文法要求,但不符合2型文法要求,因为其α=Ab,而Ab不是一个非终结符。 |
3 型文法
3型文法也叫正规文法,它对应于有限状态自动机。它是在2型文法的基础上满足:A→α|αB(右线性)或 A→α|Bα(左线性)。 α 代表的是非终结符,不一定要求字母相同。
特别注意:右线性和左线性,两套规则不能同时存在。 |
如有:A->a,A->aB, B->a, B->cB,则符合3型文法的要求。
但如果推导 为:A->ab, A->aB, B->a, B->cB
或推导 为:A->a, A->Ba, B->a, B->cB则不符合3型方法的要求了。
解释:
例子A->ab,A->aB,B->a,B->cB中的A->ab不符合3型文法的定义,如果把后面的ab,改成“一个非终结 符+一个终结符”的形式(即为aB)就对了。
例子A->a,A->Ba,B->a,B->cB中如果把B->cB改为 B->Bc的形式就对了,因为A→α|αB(右线性)和A→α|Bα(左线性)两套规则不能同时出现在一个语法中,只能完全满足其中的一个,才能算 3型文法。
正规式(正则表达式)
正规式与正规文法之间的转换:
*:代表的是大于等于0的数