目录
手撕考研数据结构(代码汇总篇)_数据结构考研代码-CSDN博客
第一章:绪论
数据结构的三要素
算法的基本概念
算法的时间复杂度
算法的空间复杂度
第二章:线性表
1.线性表的定义和基本操作
2.线性表的顺序表示
3.线性表的链式表示
单链表的创建
- 头插法:从一个空表开始,然后将新结点插入到当前链表的表头,即头结点之后。
- s->next=L->next; //新结点的指针指向原链表的第一个结点
- L->next=s; //头结点的指针指向新结点,L为头指针
- 尾插法:将新结点插入到当前链表的表尾上,为此必须增加一个尾指针,使其始终指向当前链表的尾结点。
- r->next=s; //原链表中的尾结点(r所指)的指针指向新结点
- r=s; //r指向新的表尾结点
双链表
循环链表
静态链表
对比
第三章:栈、队列和数组
栈和队列的基本性质
术语 | 定义 |
---|---|
栈 | 只允许在表的一端(栈顶)进行插入或删除的线性表。栈的操作特性为先进后出。 |
队列 | 只允许在表尾(队尾)插入,表头(队头)删除的线性表。队列的操作特性为先进先出。 |
n个不同的元素进栈,则不同出栈序列个数为
例题:字符A、B、C、D一次进入堆栈,其出栈顺序的序列有多少种:14
1.栈
2.队列
3.栈和队列的应用
栈的应用 | 队列的应用 |
---|---|
数制转换 | 层序遍历二叉树 |
括号匹配 | 缓冲区 |
表达式求值 | 进程的就绪队列 |
给定进栈和出栈顺序确定该栈的最小容量(最大深度) | 广度优先遍历BFS |
4.数组和特殊矩阵
行优先、列优先
1.对称矩阵
注:基于对称矩阵的特性可知,只需将式①的 i、j 互换即可得到④;只需将式②的 i、j 互换即可得到③;
2.三角矩阵
3.稀疏矩阵
十字链表法
第四章:串
1.串的定义和实现
2.串的模式匹配(KMP)
KMP算法
KMP算法的时间复杂度O(m+n)
- 前缀:指除最后一个字符以外,字符串的所有头部子串。
- 后缀:指除第一个字符外,字符串的所有尾部字串。
- 部分匹配值:字符串的前缀和后缀的最长相等前后缀长度。
- 匹配失败时子串需要向后移动的位数:移动位数=已匹配的字符数-最后一位匹配字符对应的部分匹配值。
next[i] = (最大 前缀 == 后缀) + 1
进一步优化
a b a a b c a c 模式值 0 1 1 2 2 3 1 2 next数组 0 1 0 2 1 3 0 2 nextval数组 1.第一位的nextval值必定为0,第二位如果于第一位相同则取相同值下的next值为0,如果不同则取当下next的值为1。 2.第三位的next值为1,那么将第三位和第一位进行比较,均为a,相同,则,第三位的nextval值为0。 3.第四位的next值为2,那么将第四位和第二位进行比较,不同,则第四位的nextval值为其next值,为2。 4.第五位的next值为2,那么将第五位和第二位进行比较,相同,第二位的next值为1,则继续将第二位与第一位进行比较,不同,则第五位的nextval值为第二位的next值,为1。 5.第六位的next值为3,那么将第六位和第三位进行比较,不同,则第六位的nextval值为其next值,为3。 6.第七位的next值为1,那么将第七位和第一位进行比较,相同,则第七位的nextval值为0。 7.第八位的next值为2,那么将第八位和第二位进行比较,不同,则第八位的nextval值为其next值,为2。
第五章:树和二叉树
1.树的基本概念
基本术语 | 定义 |
---|---|
结点的度 | 树中一个结点的子结点个数 |
树的度 | 树中结点的最大度数 |
分支结点 | 度大于 0 的结点称为分支结点 |
叶子结点 | 度等于 0 的结点称为叶子结点 |
结点的深度 | 从根结点到该结点的路径上结点的个数之和(根结点深度为1) |
树的高度 | 树中结点的最大层数(根结点为第一层) |
路径 | 树中两个结点之间所经过的结点序列 |
路径长度 | 路径上所经过的边的条数 |
- 树可以是空树(结点数=0)。
- 森林可以是空森林(树个数=0)。
树的基本性质
- 树中的结点总数等于总度数加 1(结点总数=边总数 +1)n = m + 1
度为m的树中第h层最多有 个结点。
高度为h的m叉树最多有个结点
2.二叉树的概念
术语 | 定义 |
---|---|
满二叉树 | 一棵高度为h,并且含有个结点的二叉树称为满二叉树。满结点。 |
完全二叉树 | 一棵高度为h,有n个结点的二叉树,仅当其每个结点都与高度为h hh个结点的二叉树,仅当其每个结点都与高度为h的满二叉树中编号为1 ∼ n 的结点一一对应,称为完全二叉树 |
平衡二叉树(AVL树) | 空树或者左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。 |
二叉排序树 | 左子树关键字<根节点关键字<右子树关键字 |
二叉树的顺序存储
3.二叉树的遍历和线索二叉树
遍历方式
- 先序遍历:先访问根结点,再访问左子树,最后访问右子树。
- 中序遍历:先访问左子树,再访问根结点,最后访问右子树。
- 后序遍历:先访问左子树,再访问右子树,最后访问根结点。
- 层序遍历:按自顶向下、自左向右的顺序来逐层访问树中结点。
构造二叉树
- 中序序列与前序序列。
- 中序序列与后序序列。
- 中序序列与层序序列。
唯一确定一棵二叉树的序列组合(都需要中序序列)
线索二叉树
结点结构
线索:利用空链域存放指向直接前驱或直接后继的指针。
线索化:对二叉树遍历使其变为线索二叉树。线索化时,若无左子树,则令指向其前驱结点;若无右子树,则令指向其后继结点。两个标志域表明当前指针域所指对象是指向左(右)子结点还是直接前驱(后继)。
4.树、森林
(1)双亲表示法
定义结构体,成员parent记录父节点在结构体数组中的下标
(2)孩子表示法
成员firstChild为链表指针,指向孩子结点,(并非孩子结点本身,而是记录孩子结点下标的数据结构,链表)
(3)孩子兄弟表示法
右指针指向有兄弟结点(与自己同一个父结点的结点,如E、F互为兄弟结点,H、I、J互为兄弟节点)。
森林、二叉树-互相转换
森林转二叉树
将森林所有根结点看作兄弟结点,利用孩子兄弟表示法
表示为二叉树。
二叉树转森林
5.树和二叉树的应用
哈夫曼树:带权路径长度最小的二叉树。
构造哈夫曼树
- 构造一个新结点,选取两个权值最小的结点作为新结点的左、右子树,新结点的权值置为左、右子树上根结点的权值之和。
- 从序列中删除刚才选出的两个结点,同时将新结点加入序列。
哈夫曼树特点
- 每个初始结点最终都成为叶结点,并且权值越小的结点到根结点的路径长度越大。
- 哈夫曼树中结点总数为2N−1。
- 哈夫曼树中不存在度为1的结点。
- 同一序列构造的哈夫曼树不唯一,但带权路径长度唯一且最优。
哈夫曼编码
前缀编码:没有一个编码是另一个编码的前缀。
并查集
第六章:图
1.图的基本概念
无向图 | 有向图 |
---|---|
边:顶点的无序对,记为(v,w)或(w,v) | 弧:顶点的有序对,记为<v,w>,v称为弧尾, w 称为弧头 |
无向图:若E是无向边(简称边)的有限集合时,则图G 为 无向图 | 有向图:若E是有向边(也称弧)的有限集合时,则图G为有向图 |
顶点的度:指依附于该顶点的边的数量,记为TD(v) | 顶点的度:入度和出度之和(入度是以v为终点的有向边的数目;出度是以v为起点的有向边的数目) |
连通:从顶点v到顶点w有路径存在,则称v和 w 是连通的 | 强连通:从顶点v到顶点w和从顶点w到顶点v之间都有路径,则称v和w 是强连通的 |
连通图:图中任意两个顶点都是连通的,则称图G为连通图,否则为非连通图 | 强连通图:图中任意一对项点都是强连通的,则称此图为强连通图 |
连通分量:图的极大连通子图称为连通分量 | 强连通分量:图的极大强连通子图称为有向图的强连通分量 |
无向完全图:任意两个顶点之间都存在边,共有(n-1)/2n条边 | 有向完全图:任意两个顶点之间都存在方向相反的两条弧,共有n(n−1)条有向边 |
术语 | 定义 |
---|---|
生成树 | 连通图的生成树是包含图中全部顶点的一个极小连通子图 |
生成森林 | 非连通图的连通分量的生成树构成了非连通图的生成森林 |
回路(环) | 第一个顶点和最后一个顶点相同的路径称为回路或环 |
极大连通子图 | 包含了图中尽可能多的顶点以及尽可能多的边 |
极小连通子图 | 包含图中全部顶点且包含边最少 |
图的基本概念
- 无向图中任意顶点的入度等于出度。
- 无向图中(无论是否连通),所有顶点的度数之和等于边数的两倍。
- 在有向图中,全部顶点的“入度之和”=“出度之和”=边数。
- 图的邻接矩阵表示中,各顶点的度等于矩阵中该结点对应的行(对应出度)和列(对应入度)的非零元素数量之和。
2.图的存储及基本操作
邻接矩阵存储
特点
无向图的邻接矩阵一定是一个对称矩阵,可采用压缩存储。有向图的邻接矩阵不一定是对称矩阵,有向完全图的邻接矩阵是对称矩阵。
对于无向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的度。
稠密图适合使用邻接矩阵的存储表示。
对于无权图的邻接矩阵A(矩阵中各位置的值为0或1),A n[i][j]的值表示由顶点i ii到顶点j jj的路径长度为n nn的路径的数量。
邻接表法(方式并不唯一)
区别
3.十字链表法(有向图)、邻接多重表(无向图)
基本操作:
3.图的遍历
BFS广度优先搜索 (需要一个辅助队列):
DFS深度优先搜索(需要一个栈):
4.最小生成树
生成树:
最小生成树
定义:所有生成树的集合中边的权值之和最小的那棵生成树。
性质:
- 最小生成树不唯一。
- 当图中的各边权值互不相等时,G 的最小生成树唯一。
- 最小生成树所对应的边的权值之和总是唯一的,而且是最小的。
- 最小生成树是一棵无向连通带权图。
最小生成树的生成算法:
求解最小生成树的算法主要有两个:
1.Prim(普里姆)算法;
2.Kruskal(克鲁斯卡尔)算法。
Prim 算法
每次在已选顶点的邻接边中选权值最小的边加入。
- Prim算法的时间复杂度为(|V|^2),不依赖于E,适用于边稠密的图。
Kruskal 算法
不断选取当前未被选取的权值最小的边,若其两个顶点不属于同一顶点集合,则将该边放入生成树的边集,同时将两个顶点所在的集合合并。
- 直到选取了n−1条边为止。
Kruskal算法的时间复杂度为O (∣E∣log 2∣E∣),适用于边稀疏而顶点较多的图。
差别:
5.最短路径
最短路径(权值)问题
- 单源最短路径问题:求从给定源点到其他各个顶点的最短路径长度。
- 点对点最短路径问题:求每一对顶点之间的最短路径长度。
BFS算法:
Dijkstra 算法:
算法过程:
-
dist[]:记录了从源点v0到其他各顶点当前的最短路径长度。
-
集合 S 记录已求得的最短路径的顶点,每趟确定一个最短路径
-
Floyd 算法:
三种区别
6.拓扑排序
定义
- 有向无环图的顶点组成的序列。
- 每个顶点出现且只出现一次。
- 每个有向无环图都有一个或多个拓扑序列。
算法过程:
- 从有向无环图中选择一个没有前驱的顶点并输出。
- 从图中删除该顶点和所有以它为起点的有向边。
- 直到当前的图为空或当前图中不存在无前驱的项点为止(环)。
拓扑排序的时间复杂度为 O(|V|+|E|)。
7.关键路径
AOE 网:带权有向图以顶点表示事件,有向边表示活动,边上的权值表示完成该活动的开销。
关键路径:AOE 网中从源点到汇点的最大路径长度的路径,关键路径长度是整个工程所需的最短工期。
关键活动:关键路径上的活动。
性质:
- 可以通过加快关键活动缩短整个工程的工期。并非关键活动缩短多少工期就缩短多少,因为缩短到一定的程度,该关键活动可能变成非关键活动了。
- 关键路径并不唯一。对于有几条关键路径的网,只提高一条关键路径上的关键活动速度并不能缩短整个工程的工期,只有加快那些包括在所有关键路径上的关键活动才能达到缩短工期的目的。
- 从源点到汇点的路径上,所有具有最大路径长度的路径,都是关键路径。所有“最长路径”(关键路径)上的所有活动,都是关键活动。
算法过程
求AOE网中所有事件的最早发生时间ve()
从源点出发,到该顶点的最大长度。
求 AOE 网中所有事件的最迟发生时间vl()
事件的最迟发生时间=关键路径长度-从该顶点到汇点的最大长度。
求 AOE 网中所有活动的最早开始时间e()
活动的最早开始时间=该活动的起点所代表的事件的最早发生时间。也就是从源点出发,到这条边的起始点的最大长度。
求 AOE 网中所有活动的最迟开始时间l()
活动的最迟开始时间=关键路径长度-(从这条边的终点到汇点的最大长度 + 这条边的长度)。
求 AOE 网中所有活动的差额d()=l()−e(),找出所有d()=0(最早开始时间=最迟开始时间)的活动构成关键路径。若活动的最迟开始时间 > 最早开始时间,则该活动不是关键活动。
第七章:查找
1.查找的基本概念
- 关键字:唯一标识数据元素的数据项。
- 查找长度:在查运算中,需要对比关键字的次数称为查找长度。
- 平均查找长度(ASL):所有查找过程中进行关键字比较次数的平均值。
***考点:计算各种查找的ASL(画出查找树)。考察查找判定树。***
2.顺序查找和折半查找
顺序查找(考的相对多一点)
折半查找(二分查找):
仅适用于顺序表
绿色成功,紫色失败
3.分块查找(选择题)
块内无序、块间有序
3.树形查找
1.二叉排序树
性质
- 若它的左子树不空,则左子树上所有结点的值均小于它根结点的值。
- 若它的右子树不空,则右子树上所有结点的值均大于它根结点的值。
- 它的左、右树又分为⼆叉排序
显然,二叉排序树与二叉树一样,也是通过递归的形式定义的。因此,它的操作也都是基于递归的方式。
2.平衡二叉树( AVL )
性质:
- 可以是空树
- 假如不是空树,任何⼀个结点的左子树与右子树都是平衡⼆叉树,并且高度之差的绝对值不超过 1。
平衡二叉树最大的作用就是查找
AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)
插入方式 | 描述 | 旋转方式 |
---|---|---|
LL | 在结点A的左孩子的左子树插入导致A失衡 | 右旋 |
RR | 在结点A的右孩子的右子树插入导致A失衡 | 左旋 |
LR | 在结点A的左孩子的右子树插入导致A失衡 | 先左旋再右旋 |
RL | 在结点A的右孩子的左子树插入导致A失衡 | 先右旋再左旋 |
平衡二叉树的删除
删除结点的类型:
- 删除叶子结点
- 删除结点只有左子树
- 删除结点只有右子树
- 删除结点有左、右子树
3.红黑树
红黑树性质:
- 节点是红色或黑色
- 根是黑色
- 叶子节点(外部节点,空节点)都是黑色,这里的叶子节点指的是最底层的空节点(外部节点),下图中的那些null节点才是叶子节点,null节点的父节点在红黑树里不将其看作叶子节点
- 红色节点的子节点都是黑色
- 红色节点的父节点、子节点都是黑色
- 从根节点到叶子节点的所有路径上不能有 2 个连续的红色节点
- 从任一节点到叶子节点的所有路径都包含相同数目的黑色节点
左根右,根叶黑
不红红,黑路同
插入:先查找确定插入位置
- 新节点是根节点--染为黑色
- 新节点是非根节点--染为红色
- 若加入后满足红黑树的定义,结束插入
- 若不满足,需要调整
- 黑叔:旋转+染色
- LL型:右单旋,父换爷 + 染色
- RR型:左单旋, 父换爷 + 染色
- LR型:左右双旋,儿换爷 +染色
- RL型:右左双旋,儿换爷 + 染色
- 红叔:染色 +变新,叔父爷染色,爷变新结点
4.B树和B+树
1.B树
B树的定义
一颗m阶的B树满足如下条件:
- 每个节点最多只有m个子节点。
- 除根节点外,每个非叶子节点具有至少有 m/2(向下取整)个子节点。
- 非叶子节点的根节点至少有两个子节点。
- 有k颗子树的非叶节点有k-1个键,键按照递增顺序排列。
- 叶节点都在同一层中。
2.B+树
B+树的定义
一颗m阶的B+树满足如下条件:
- 每个节点最多只有m个子节点。
- 除根节点外,每个非叶子节点具有至少有 m/2(向下取整)个子节点。
- 非叶子节点的根节点至少有两个子节点。
- 有k颗子树的非叶节点有k个键,键按照递增顺序排列。
- 叶节点都在同一层中。
5.散列表
第八章:排序
1.排序的基本概念
2.插入排序
3.希尔排序
4.冒泡排序
5.快速排序
从数列中挑出一个元素,称为 "基准"(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
6.简单选择排序
7.堆排序
8.归并排序
9.基数排序
(计数排序)(不考)
10.外部排序
408数据结构学习笔记——外部排序_考研外部排序笔记-CSDN博客