数据结构知识汇总

1 线性表

因为数据元素是一对一的关系,即线性关系,故称为线性表。

  1. 顺序表
  2. 线性链表
    单链表、循环链表、双向链表
  3. 数组
    数组是线性表的推广,是由一组具有相同特性的数据元素组成。
    矩阵的压缩存储
    三角矩阵、稀疏矩阵(三元组表法【行、列、值】、十字链表法【行、列、值、下、右】)

2 栈与队列


  1. 先进后出(LIFO)
    顺序栈、链栈
    应用算术表达式(中缀和后缀)、Hanoi塔
    中缀转换成后缀的流程:
    ①将@压入运算符栈;
    ②若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;
    ③如遇到运算符,则必须与栈顶比较,运算符级别比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作为分隔符;
    ④如遇到左括号,进栈,若遇到右括号,则一直退栈输出,直到退到左括号为止。
    ⑤当栈为空时,输出结构即为后缀表达式。
  2. 队列
    先进先出(FIFO)
    顺序队列、循环队列(front=rear为空,(rear+1)%MAXLEN=front为满)、链队列
    假溢出:尾指针指向末尾,但前面有元素已经出队,这时要插入元素,虽然队列并未满,但还会溢出。
    应用:打印数据缓冲

3 串

串是一种特殊的线性表,它的数据对象是字符集合。
顺序串(紧缩存储和非紧缩存储)、链串、索引存储

4 树

树是以分支关系定义的层次结构,可以有顺序存储和链式存储两种存储方式。

4.1 链式树

这里主要介绍三种常用的链表结构。
双亲表示法【值,双亲的位置】
这种存储结构利用了每个结点(除根以外)只有唯一的双亲的性质,很容易由孩子找到双亲,但无法从双亲找到孩子。
多重链表表示法(定长结点型【每个结点的指针域个数为树的度数】和不定长结点型【每个结点的指针域个数为该结点的度数】)
孩子-兄弟链表表示法【值,指向该结点第一个孩子的结点的指针,指向该结点下一个兄弟结点的指针】

4.2 二叉树

二叉树是结点的有限集合,这个集合或者为空集,或者是由一个根节点和两棵互不相交的分别称为这个根节点的左右子树的二叉树组成。
满二叉树(结点全满)、完全二叉树(缺最右下角)

  1. 二叉树的性质
    ①在二叉树的第i层上至多有 2 i − 1 2^{i-1} 2i1个结点 i ⩾ 1 i\geqslant 1 i1
    ②深度为 k k k的二叉树至多有 2 k − 1 2^k-1 2k1个结点 k ⩾ 1 k\geqslant 1 k1
    ③对任何一颗二叉树 T T T,如果其终端结点数为 n 0 n_0 n0,度为2的结点数为 n 2 n_2 n2,则:
    n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1

    解:设 n 1 n_1 n1为度为1的结点数,则总结点数
    n = n 0 + n 1 + n 2 n=n_0+n_1+n_2 n=n0+n1+n2
    二叉树中除根节点外其他结点都有一个指针与其双亲相连,若指针数为b,满足
    n = b + 1 n=b+1 n=b+1
    而这些指针又可以看作由度为1和度为2的结点与它们孩子之间的联系,于是
    b = n 1 + 2 n 2 b=n_1+2n_2 b=n1+2n2
    合并可得:
    n = n 1 + 2 n 2 + 1 n=n_1+2_n2+1 n=n1+2n2+1
    所以
    n 0 = n 2 + 1 n_0 = n_2 +1 n0=n2+1
    ④具有n个结点的完全二叉树的高度为 ⌊ l o g 2 n ⌋ + 1 \left \lfloor log_2n\right \rfloor+1 log2n+1
  2. 二叉树的存储结构
    顺序存储和链式存储
  3. 二叉树的遍历
    先序遍历、中序遍历、后序遍历
    层次遍历(用循环队列实现)

4.3 线索二叉树

lchildltagdatartagrchild
若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其直接前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild域指示其直接后继。
其中,
ltag=0时表示lchild指示结点的左孩子。
ltag=1时表示lchild指示结点的直接前驱。
ltag=0时表示rchild指示结点的右孩子。
ltag=1时表示rchild指示结点的直接前驱。
这种结构的的结点构成的二叉链表作为二叉树的存储结构叫做线索链表;其中指向结点直接前驱和后继的指针叫做线索;加上线索的二叉树称为线索二叉树。

4.4 二叉排序树

二叉排序树是利用二叉树的结构特点来实现排序,把结点的一组无序元素按一定的规则构造成一棵二叉树,使其在中序遍历下是有序。
性质
①若其左子树非空,则其左子树上的所有节点的数据值均小于根节点的数据值;
②若其右子树非空,则其右子树上所有的结点的数据值均大于或等于根节点的数据值。

4.5 平衡二叉树

平衡二叉树是不断地调整二叉树的结构,进行“平衡化”处理,使二叉树保持一定的平衡状态,维持较高的查找效率。
性质:它的左子树和右子树的高度之差的绝对值不超过1。
平衡调整规则:LL型平衡旋转、RR型平衡旋转、LR型平衡旋转、RL型平衡旋转

4.6 树、森林与二叉树的转换

  1. 一般树转换成二叉树
    加线(兄弟结点之间加线)、抹线(只保留它与第一个孩子之间的连线,删除它与其他孩子结点之间的连线)、旋转
    在这里插入图片描述
  2. 森林转换成二叉树
    每个树转换成二叉树,最后连接成一颗二叉树。在这里插入图片描述
  3. 二叉树转换成树
    删掉与右结点之间的连线,右孩子结点全接到双亲结点上。在这里插入图片描述
  4. 二叉树转换成森林
    同上,多加一个虚根。

4.7 哈夫曼树

最优二叉树,是一类带权路径长度最短的树。
哈夫曼算法
①根据给定的n个权值构成n棵二叉树的集合F,其中每棵二叉树中只有一个带权的根节点;
②在集合F中选择两棵根结点最小的树作为左右子树构造一棵新的二叉树T,且置新的二叉树的根节点的权值为其左右子树上根节点的权值之和;
③将新的二叉树T加入到集合F中,从二叉树集合中去除原来两棵根结点权值最小的树。
④重复2、3步直到F中只含一棵树位置,这棵树就是哈夫曼树。
在这里插入图片描述
应用:哈夫曼编码

4.8 B树

B树包含B-树和B+树两种,是一种适用于外检索的树,是一种平衡的多叉树。

  1. B-树的定义
    一棵m阶的B-树或者是一棵空树,或者是满足下列特征的m叉树:
    ①树中每个结点至多有m棵子树;
    ②若根结点不是叶子结点,则至少有两棵子树;
    ③除根之外的所有非终端结点至少有 ⌈ m / 2 ⌉ \left \lceil m/2 \right \rceil m/2 ⌈ ⌉ \left \lceil \right \rceil 符号表示上取整);
    ④所有的非终端结点中包含下列信息数据
    ( n , A 0 , K 1 , A 1 , K 2 , A 2 , . . . , K n , A n ) (n,A_0,K_1,A_1,K_2,A_2,...,K_n,A_n) (n,A0,K1,A1,K2,A2,...,Kn,An)
    其中: K i K_i Ki为关键字,且 K i &lt; K i + 1 K_i&lt;K_{i+1} Ki<Ki+1
    A i A_i Ai为指向子树根结点的指针,且指针 A i − 1 A_{i-1} Ai1所指子树中所有结点的关键字均小于 K i K_i Ki A i A_i Ai所指子树中所有结点的关键字均大于 K i K_i Ki,n( ⌈ m / 2 ⌉ − 1 ≤ n ≤ m − 1 \left \lceil m/2\right \rceil-1 \leq n \leq m-1 m/21nm1)为关键字的个数。
    ⑤所有的叶子结点都出现在同一层上,并且不带信息。
    在这里插入图片描述

  2. B-树的检索

  3. B-树的插入

  4. B-树的删除

5 图

完全图(每两个点之间都有一条边)
连通图(无向图中,任意两顶点都是连通的,即有路劲连接)
强连通图(有向图中,任意两顶点之间都有双向的路径)
连通分量(无向图中极大连通子图)
强连通分量(有向图中极大强连通图)
邻接矩阵、邻接表、边集数组
深度优先(DFS)广度优先(BFS)

5.1 最小生成树

选择一棵生成树,使所花费的总代价最小,这就是构造连通网的最小生成树问题,即在连通网中,构造边上的代价总和最小的生成树

  1. 普里姆算法(Prim)——任选一点,再选最小边
    ①按照将顶点逐个连通的步骤,把已连通的顶点加入到集合U中,这个集合U开始时为空集;
    ②首先任选一个顶点加入U,然后从依附于该顶点的边中选取权值最小的边作为生成树的一条边,并将依附于该边且在集合U外的另一顶点加入到U,表示这两个顶点已通过权值最小的边连通了。
    ③以后每次从一个顶点在集合U中,而另一个顶点在U外的各条边中选取权值最小的一条,作为生成树的一条边。
    ④以此类推,直到全部顶点都已连通,即构成所要求的的最小生成树。
  2. 克鲁斯卡尔算法(Kruskal)——依次选择最小边
    ①假设连通网N=(V,E),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,E1),其中E1为空集,即T中的每个顶点自成一格连通分量;
    ②在E中选择权最小的边,若该边依附的顶点落在T中不同的分量上,则将此边加入到T中,否则舍去此边选择下一条权最小的边。
    ③以此类推,直到T中所有顶点都在同一连通分量上。

5.2 最短路径

  1. 迪杰斯特拉算法(Dijkstra)——求某个源点到其他各顶点的最短路径(起点开始,有小则换
    思想:Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。
    流程:设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,对 v i v_i vi∈V-S,假设从源点 v 0 v_0 v0 v i v_i vi的有向边为最短路径。以后每求得一条最短路径 v , … , v k v, …, v_k v,,vk,就将vk加入集合S中,并将路径 v , … , v k v, …, v_k v,,vk , v i v_i vi与原来的假设相比较,取路径长度较小者为最短路径。重复上述过程,直到集合V中全部顶点加入到集合S中。
  2. 弗洛伊德算法(Floyed)——求每一对顶点之间的最短路径(任两点,寻找第三点,使权变小则换
    Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释。
    从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
    动态转移方程:
    A − 1 [ i ] [ j ] = c o s t [ i ] [ j ] A^{-1}[i][j]=cost[i][j] A1[i][j]=cost[i][j]
    A k [ i ] [ j ] = m i n ( A k − 1 [ i ] [ j ] , A k − 1 [ i ] [ k ] + A k − 1 [ k ] [ j ] ) A^k[i][j]=min(A^{k-1}[i][j],A^{k-1}[i][k]+A^{k-1}[k][j]) Ak[i][j]=min(Ak1[i][j],Ak1[i][k]+Ak1[k][j])

5.3 拓扑排序

利用没有回路的有向图描述一项工程或对工程的进度进行描述是非常方便的。

  1. AOV网
    在有向图中若以顶点表示活动,用有向边表示活动之间的优先关系,则这样的有向图称为以顶点表示活动的网,简称AOV网。如果要检测一个工程是否可行,首先就得检查对应的AOV网是否存在回路。检查AOV网中是否存在回路的方法就是拓扑排序。
  2. 拓扑排序
    拓扑有序序列:它是由AOV网中所有顶点构成的一个线性序列,在这个序列中体现了所有顶点间的优先关系。
    对AOV网进行拓扑排序的步骤是:
    ①在网中选择一个没有前驱的顶点且输出之;
    ②在网中删去顶点,并且删去从该顶点出发的全部有向边
    ③重复上述两步,直到网中不存在没有前驱的顶点为止。
    这样操作后的结果有两种:一种是网中全部顶点均被输出,说明网中不存在有向回路;另一种是网中顶点未被全部输出,剩余的顶点均有前驱顶点,说明网中存在有向图

5.4 关键路径

在带权有向图中,以顶点表示事件,以弧表示活动,弧上的权表示活动持续的时间,则此带权有向图称为用边表示活动的网,简称AOE网。通常,AOE网可用来估算工程的完成时间。
对于AOE网,人们关心的是:①完成整个工程需要多少时间;②哪些活动时影响工程进度的关键。
AOE网可以并行工作,所以完成工程的最短时间是从源点到汇点的最长路径长度,即路径上权数之和。路径长度最长的路径称为关键路径,关键路径上的活动称关键活动

6 查找

6.1 顺序查找

顺序查找也称为线性查找,它的基本思想使用给定的值与表中各个记录的关键字值逐个进行比较,若找到相等的则查找成功,否则查找不成功。(从后向前查找 n + 1 2 \frac{n+1}{2} 2n+1

6.2 二分法查找

基本思想:先取表的中间记录的关键字值与给定关键字的值相比较,如果给定值比该记录的关键字值大,则要查找的记录一定在表的后半部分;若给定值比该记录的关键字值小,则要查找的记录一定在表的前半部分。(下取整 l o g 2 ( n + 1 ) − 1 log_2(n+1)-1 log2(n+1)1

6.3 分块查找

分块查找又称索引顺序查找,介于顺序查找和二分法查找之间的一种折中查找方法。
基本思想:把线性表分成若干块,在每一块中数据元素的存放次序是任意的,但是块与块之间必须有序。假设是按关键字值递增次序排列,也就是说在第一块任一数据元素的关键字值都小于第二块中任一数据元素的关键字值,以此类推。另外还要建立一个索引表,把每块中最大的关键字值按关键字值大小存入索引表,使索引表保持为有序表。 n + 1 \sqrt{n}+1 n +1

6.4 散列法(哈希法)

基本思想:以记录中的关键字的值为自变量,通过确定的函数H(散列函数)进行计算,求出对应的函数值,把这个函数值作为存储地址,将该记录存放在这个位置上,查找时扔按这个确定的函数H进行计算,获得的将是待查的关键字所在记录的存储地址。

  1. 散列函数的构造方法:
    ①直接定址法
    ②数字分析法
    ③平方取中法
    ④折叠法
    ⑤除留余数法
  2. 冲突处理
    ①开放地址法(空闲单元既向同义词元素开放,也向发生冲突的非同义词元素开放。也分为线性探查法、平方探查法和双散列函数探查法)
    ②链接法(把发生冲突的同义词元素用单链表链接起来) 1 + α 2 1+\frac{α}{2} 1+2α

7 排序

7.1 插入排序

  1. 直接插入—— O ( n 2 ) O(n^2) O(n2)——从后向前比
  2. 折半插入—— O ( n 2 ) O(n^2) O(n2)——折半查找插入
  3. 2-路插入——空间换时间
  4. 希尔排序—— O ( n l o g 2 n ) ∼ O ( n 2 ) O(nlog_2n)\sim O(n^2) O(nlog2n)O(n2)——缩小增量排序
    d d d分段插入
    d 2 \frac{d}{2} 2d分段插入
    。。。
    1 1 1分段插入

7.2 选择排序

  1. 简单选择排序—— O ( n 2 ) O(n^2) O(n2)——每趟选最小的顺序放在已排序的序列最后
  2. 堆排序—— O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
    ①建立大顶堆,去除堆顶元素;
    ②然后把剩下的记录再排成堆,取出堆顶元素,依次进行。

7.3 交换排序

  1. 冒泡排序—— O ( n 2 ) O(n^2) O(n2)——相邻比较,大的沉底
  2. 快速排序——平均 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n),最坏 O ( n 2 ) O(n^2) O(n2)——二路交换

7.4 归并排序

  1. 2-路归并—— O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)——两两归并。

7.5 基数排序

  1. 多关键字排序
  2. 链式基数排序
    总结
    稳定性排序:
    不稳定性排序:
类别量级排序类别
时间复杂度 O ( n 2 ) O(n^2) O(n2)直接插入、简单选择、堆排序、快速排序
时间复杂度 O ( n l o g 2 n O(nlog_2n O(nlog2n堆排序、归并排序、快速排序(最差 O ( n 2 ) O(n^2) O(n2)
时间复杂度 O ( n l o g 2 n ) ∼ O ( n 2 ) O(nlog_2n)\sim O(n^2) O(nlog2n)O(n2)希尔排序
时间复杂度 O ( d ( n + r ) ) O(d(n+r)) O(d(n+r))基数排序
稳定性稳定性排序直接插入、冒泡排序、归并排序、基数排序
不稳定性不稳定性排序希尔、简单选择、堆排序、快速排序
空间复杂度 O ( n ) O(n) O(n)归并排序
空间复杂度 O ( l o g 2 n O(log_2n O(log2n快速排序
空间复杂度 O ( 2 r ) O(2r) O(2r)基数排序
空间复杂度 O ( 1 ) O(1) O(1)其他

①元素的移动次数与关键字初始排列无关:基数排序
②元素的比较次数与关键字初始排列无关:选择排序
③排序的时间复杂度与关键字初始排列无关:直接选择

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值