数据结构相关重点(个人总结)

本文全面梳理数据结构基础知识,包括线性表、栈、队列、串、树与二叉树、图、查找与排序等内容,重点突出易错点与考试要点。

一些注意事项

  • 文章中提到的的题目、页码来自2021版王道数据结构
  • 内容为本人手打总结的一些数据结构中的易错或容易被忽视的知识点
  • 主要面向考试(考研、期末),不适用于单纯想了解一下数据结构知识的朋友
  • 建议有数据结构学习基础的朋友阅读
  • 如有错漏,烦请指出,感激不尽

  • 一、绪论

        从小到大:

        数据项  数据元素  数据对象(相同性质数据元素的集合

  • 二、线性表

2.1 线性表

  1. 线性表可以为空表。(可以为空树。图的顶点集不能为空边集可以为。)
  2. 线性表有限、每个数据元素都是单个元素
  3. 表中元素具有逻辑上的顺序性,表中元素有先后次序。
  4. 每个元素占有相同大小的存储空间。
  5. 线性表是逻辑结构,顺序表、链表是存储结构。

2.2 线性表的顺序表示

        1. 顺序表:逻辑上相邻,物理位置上也相邻。逻辑顺序与物理顺序相同。

        2. 数组下标(一般从0开始)和元素位序(从1开始)不同。

        3. 顺序表初始动态分配语句:

                C: L.data = (ElemType*)malloc( sizeof( ElemType ) * InitSize);

                CPP:L.data = new ElemType[InitSize];

        4. 顺序表存储密度

        5. 顺序表插入元素平均移动次数:n/2

        6. 顺序表删除元素平均移动次数:(n-1) /2

        7. 交换第3个元素和第4个元素的值,顺序表比链表高效(因为不是单纯地交换两个元素,链表需要找到第3、第4元素的前驱)

2.3 线性表的链式表示 

  1. 头结点优点:
    *链表在第一个位置上的操作和在表的其他位置上的操作一致
    *空表非空表处理一致

  2. 对链表进行修改的,函数参数需要加&地址符。

  3. 创建指针变量:LNode *s;
  4. 单链表访问后继节点O(1),访问前驱结点O(n);
  5. 删除结点记得free();
  6. 循环单链表,在表头表尾都要进行操作时,选择设尾指针。设头指针操作表尾需要O(n),设尾指针操作表头表尾都只需O(1);
  7. 循环双链表 = 双循环链表
  8. 静态链表顺序表的区别:静态链表的插入、删除只需要修改指针,不需要移动元素。
  9. 顺序表随机存取链表顺序存取
  10. 链表空间分配操作灵活、高效。
  11. 链式存储结构的存储密度小于1;
  12. 顺序表实现较简单
  13. 循环单链表:尾指针指向表头,头指针(如果有的话)不能指向表尾。即只有队首指针的循环单链表无法直接访问表尾。只有队尾指针的循环单链表可以直接访问表头表尾。错题P39 19
  14. 循环双链表:尾指针指向表头,头指针也可以指向表尾,因此有一个就行。即只有队首指针或只有队尾指针的循环双链表(有任意一个就行)可以直接访问表头表尾。错题P39 20
  15. 将长度为n的单链表链接在长度为m的单链表后面,时间复杂度为O(m)
  16. 为了方便插入和删除数据,可以使用双链表存放数据。

  • 三、栈和队列

3.1 栈

  1. 栈可以为空栈
  2. 卡特兰(Catalan)数:n个不同的元素进栈,出栈元素不同的排列个数为[1/(n+1)]*Cn2n
  3. 注意区分栈顶指针top指向栈顶元素或栈顶元素下一位的情况,这两种情况下出入栈的操作有所不同(先+-下标再读栈,还是先读栈再+-下标。)
  4. 共享栈:两个栈的栈顶指针都指向栈顶元素,top0 = -1时0号栈为空,top1 = MaxSize时1号栈为空。top1 - top0 = 1时,栈满

        

注意是b op a

3.2 队列

  1. 循环队列:

        队首指针进1:Q.front = (Q.front + 1) % MaxSize;       (MaxSize指最大容量,不是下标。例如A[0..6],MaxSize为7。)

        队尾指针进1:Q.rear = (Q.rear + 1) % MaxSize;

        队列长度:(Q.rear + MaxSize - Q.front) % MaxSize;

        队满条件:(Q.rear + 1) % MaxSize = Q.front;   (即留了一个空白的位置,作为判断是否队满的依据。此时队尾指针指向队尾元素的下一位队头指针指向队头元素。)

        队空条件:Q.front = Q.rear;

        队中元素个数:(Q.rear - Q.front + MaxSize) % MaxSize;  (注意是尾减头)

    2. 带头结点的链队列,执行出队操作时,如果当前结点是队列中最后一个结点,删除该结点后,需要把队尾指针指向头结点。

3.3 栈和队列的应用

        1. 后缀计算表达式值:扫描到操作符<op>时,连续从栈中退出两个操作数X,Y,形成运算指令X<op>Y(注意X,Y的顺序,是X<op>Y)。

        2. 注意中缀表达式转后缀的方法和过程。P94 2、P95 11、P96 12

        3.对于一个问题的递归算法求解和其对应的非递归算法求解,非递归算法通常效率高一些。

四、串

        1. 字符串’aba’ 前缀为a,ab。后缀为a,ba(注意不是ab)。

        2. KMP:O(n+m)

        3. next数组求法:求出子串各位置最大相等前后缀长度;向右移一位;加1。

        4. nextval数组求法:P118 7多做几遍

        第一步:令nextval[1] = next[1] = 0; (next数组是右移加1的版本,从j = 1向j= n方向判断)

        第二步:从j = 2开始,依次判断pj是否等于Pnext[j]?将next[j]修正为next[next[j]],直至pj不等于Pnext[j]为止:continue;

五、树与二叉树

5.1 树的基本概念

        1. 树的根节点没有前驱,除根节点外所有结点有且只有一个前驱。

        2. 树中所有结点可以有零个或多个后继(1对多)

        3. 度大于0的结点称为分支节点(又称非终端结点)(根结点也算

        4. 结点深度根结点开始向下逐层累加,结点高度叶结点开始自底向上逐层累加。

        5. 路径是结点序列。路径长度是边的个数(树中路径自上向下)。

        6. 森林是m(m >= 0。0棵、1棵也算森林)棵互不相交的树之集合。

        7. 树的性质

                1)树中结点数 = 所有结点度数 + 1;

                2)度为m的树,第i层上至多有mi-1个结点(i >= 1)。

                3)高度为h的m叉树至多有(mh-1)/(m - 1)个结点。

                4)具有n个结点的m叉树最小高度logm(n(m - 1) + 1)

        8. 树的路径长度是从树根到每个结点路径长度的总和。

5.2 二叉树的概念

  1.   二叉树是有序树。叉树将其左、右子树颠倒,则成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分左右子树。

  2.   二叉树与度为2的有序树区别:

            

  3. 完全二叉树:若有度为1的结点,则只可能有一个,且该结点只有左孩子而无右孩子。

  4. 二叉树的性质:非空二叉树上的叶子结点数等于度为2的节点数加1,即n0 = n2 + 1。
  5. 非空二叉树第k层至多2^(k-1)个结点。
  6. 高度为h的二叉树至多2^h - 1个结点。
  7. 结点i所在层次(深度)为log2i+ 1
  8. 具有n(n > 0)个结点的完全二叉树高度(5.1.7.4)中为最小高度)log2(n + 1)
  9. 含有n个结点的二叉链表中,含有n + 1个空链域。(2n0 + n1 = n0 + n2 + 1 + n1 = n + 1)
  10. 若n为奇数,则每个分支结点都有左孩子和右孩子;若n为偶数,则编号最大的分支结点(编号n/2)只有左孩子,没有右孩子。(用于选择题,判断最后一层叶子结点数量,或者知道n0和n,判断n1数量)P133 16

5.3 二叉树的遍历和线索二叉树

        1. 三种遍历算法(先、中、后序) 时间复杂度都是O(n),递归空间复杂度恰好为树的深度,最坏能到O(n)

        2. 在二叉树中有结点n、m,若m是n祖先,则使用后序遍历可以找到m到n路径。

        3. 二叉线索树是一种物理结构

        4. 在中序线索树中,若某结点有左孩子,则其前驱结点是它的左子树最右下结点 P148 27

        5. 后序线索树的遍历仍需要栈的支持(线索树的遍历相当于找后驱,后序后驱需要栈

        6. 先序序列为a,b,c,d的不同二叉树个数为14(卡特兰数,先序入栈,中序出栈)P149 34

5.4 树、森林

        1. 树和森林的遍历与二叉树遍历的对应关系

        

5.5 树与二叉树的应用

         1. 二叉排序树的删除

                1)右子树空,用左子女填补。

                2)左子树空,用右子女填补。

                3)左右子树均不空,在右子树上找中序第一个子女填补。 P185 图5.24

         2. 二分查找的判断树唯一,而二叉排序树的查找不唯一

        3. 有序表静态查找表时,宜用顺序表作为其存储结构;有序表是动态查找表,则应选择二叉排序树作为其逻辑结构

        4. 平衡二叉树的插入

                1)LL平衡旋转。(旋转左孩子

                2)RR平衡旋转。(...右孩子

                3)LR平衡旋转。(...左孩子右子树根节点

                4)RL平衡旋转。(...右孩子左子树根节点

        P187

        5. 平衡二叉树高度公式

                n0 = 0, n1 = 1, n2 = 2;

                nh = nh-1 + nh-2 + 1(1是根节点)

        6. 哈夫曼树的权值来自结点。

        7. 哈夫曼树特点:

                1. 每个初始结点最终都成为叶结点,且权值越小的结点到根节点的路径长度越大。

                2. 构造过程中新建了n - 1个结点双分支结点),因此哈夫曼树总结点数2n - 1

                3. 每次都选择两棵树作为新结点的孩子,因此哈夫曼树中不存在度为1的结点

        8. 度为m的哈夫曼树中,叶子结点个数为n,则非叶子结点个数为:(n - 1)/(m - 1)

                解释:每层m - 1个,最底层m个,设除最底层第一层外有x层。

                即n = x(m - 1) + m。

                所以x = (n - m)/(m - 1)。又非叶子结点个数为:x + 1(1是根结点)

                所以x + 1 = [(n - m) + (m - 1)] / (m - 1),(n - 1)/(m - 1)

        9. 所有非叶结点的平衡因子均为1,即平衡二叉树满足平衡的最少结点情况。 P193017

6.1 图的基本概念

  1. 图的边集可以为空,顶点集不能为空。
  2. 有向图中,有箭头的那边是弧头。
  3. 简单图:不存在重复边和自环。
  4. 完全图:无向:n(n - 1)/2;有向:n(n - 1)
  5. 子图:(v属于V)&&(e属于E)
  6. 生成子图:包含所有顶点。
  7. 连通分量:极大连通子图包含其所有的边)连通子图(无向图)
  8. 图有n个顶点,边小于n-1(等于n-1也未必连通,有环情况下),必不连通。
  9. 极大连通子图包含其所有的边
  10.          极小保持图连通的最少边
  11. 强连通图(有向图):有路径就行,不需要直接相连。
  12. 生成树:连通图的一个极小生成子图
  13. 无向图的度:2e
  14. 有向图的度:e(一个出/入度代表了一条边)
  15. 网:带权图
  16. 环不是简单路径
  17. 除第一个和最后一个顶点外,其余顶点不重复出现的回路称为简单回路
  18. 若一个具有n个顶点,e条边的无向图是一个森林,则该森林中必有n - e棵树 P213 18

6.2 图的存储及基本操作

        1. 设图G的邻接矩阵为A,An的元素An[i][j]等于由i到j长度为n的路径数目。

        2. 无向图的邻接矩阵一定对称且唯一。

        3. 无向图邻接表存储空间O(|V| + |2E|)

        4. 邻接矩阵用法:遍历

                P =G.vertices[i].firstarc;

                P = p->nextarc;

6.3 图的遍历

        1. 图的广度优先搜索算法是二叉树的层次遍历算法的扩展。

        2. 邻接矩阵:BFS/DFS生成树唯一;邻接表:BFS/DFS生成树不唯一。

        3. BFS和DFS:对每个连通分量调用一次。

        4. 基于邻接矩阵的遍历所得到的的DFS序列和BFS序列唯一,基于邻接表的不唯一。

        5. DFS/BFS:空O(V),时(表O(V+E),矩阵O(V2))

        6. Dij不能带负权环/负权边

        7.拓扑:有向无环图,顶点表示活动。时间复杂度邻接表O(V+E),邻接矩阵O(n2)。

        8. 拓扑排序算法:

                1)从AOV网中选择一个没有前驱的顶点输出。

                2)删除该顶点和以它为起点的有向边。

                3)重复1)、2)直到当前AOV网为空或当前网中不存在无前驱结点为止。后一种情况说明有向图中存在环。

                当一个顶点有多个后继结点,拓扑结果通常不唯一;如果各顶点线性有序,有唯一前后继,则拓扑唯一。

                充分条件:

                邻接矩阵是三角矩阵 --> 存在拓扑序列

        9.AOE(Activity On Edge)顶点表示事件,有向边表示活动。

        10. AOE中边有权值,AOV中没有。

                1)不能随意缩短关键活动,缩太短可能变成非关键路径。

                2)对于多条关键路径,同时缩短才能达到缩短工期的目的。

                3)若有向图拓扑有序序列唯一,则图中每个顶点的入度和出度最多为1(X)P249 14

                4)若有向图拓扑有序序列唯一,则可以唯一确定该图 (X) 同上 P250 19

  • 查找

7.1 ~ 7.2 二分、顺序查找

  1. 二分:元素个数为n时树高h=log2(n + 1)(也是关键字比较的最多次数,最多次数与最少次数相差1)与具有n(n > 0)个结点的完全二叉树高度相同。
  2. 一般线性表和有序线性表,顺序查找的成功ASL相同,都是(n + 1)/2。
  3. 顺序查找失败ASL=n+1,有序顺序表查找失败ASL = n/2 + n/(n + 1)
  4. 对2500个记录的索引顺序表(分块表)进行查找,最理想的块长为n1/2  P277 17、19

7.3 B树和B+树

B树:

        每个结点至多m棵子树,即至多含有m - 1个关键字

        1. 若根结点不是终端结点,则至少两棵子树。

        2. 除根结点外的所有非叶结点至少m/2棵子树,即至少含有m/2 - 1个关键字。

        3. 外部结点也算孩子结点,但不计入树高

        4. B树高度:logm(n+1) <= h <= logm/2((n+1)/2) + 1

        5. 具有n个关键字的m阶B树,应该有n+1个叶结点

        6. 含有n个非叶结点的m阶b树至少包含(n - 1)(m/2 - 1) + 1个关键字(即根结点1个关键字,其它的m/2 - 1个关键字

        7. B树不支持顺序查找

        8. B+树更适合操作系统的文件索引、数据库索引,B树B+树都可以用于文件索引。

7.4 散列表

        1. 散列表平均ASL:比较次数*个数之和除以总元素个数。

        2. 装填因子α:(表中记录数n)/(散列表长度m)

        3. 散列表的平均查找长度依赖于装填因子α,不直接依赖于n、m;

        4. α越大,表越满,冲突概率越高。

        5. P300 18 查找失败平均长度。

        6. 聚集是因选取不当的冲突处理方法。

        7. 散列查找的效率取决于:散列函数、处理冲突的方法和装填因子。

八、排序

        1. 对同一线性表使用不同的排序方法进行排序,得到的排序结果可能不同。

        2. 对n个关键字排序的比较次数至少为log2(n!)

        3. P322 对下列关键字进行快速排序,最快的是:每次枢轴能把数据划分成两半(就是一半比枢轴小,一半比枢轴大,和元素的位置无关)

        4. 不可能为快排第二趟结果的:每一个分块,一趟都要确定一个元素的最终位置。如果第一趟分成了两块,那么第二趟就要确定三个元素的位置。P323 17

        

        5. 排序的稳定性

        

        6. 向堆插入删除结点时间复杂度为O(lgn)

        7. 建堆时间复杂度为O(n),堆排序时间最坏也是O(lgn)

        8. n个元素进行k路归并,排序趟数m = logkn

        9. 基数排序所需空间复杂度O(r) r为进制。所需时间复杂度为O(d(n+r)) d为趟数

        10. 基数排序时间复杂度与序列初始状态无关

        11. 归并排序平均情况下、最坏情况下空间复杂度皆为O(n),快排平均情况下空间复杂度为O(lgn),最坏情况下空间复杂度为O(n)。

        12. 大文件用归并排序,因为涉及到外部排序。

        13. 各种排序算法的性质

        

        14. 若要求排序稳定,且关键字为实数,选择直接插入排序。

        15.直接插入排序趟数(注意不是比较次数)也与原始状态无关。

        16.(有序顺序表,二叉排序树,堆,平衡二叉树)查找效率最低的是堆,因为堆是用来排序的,不是查找的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值