简介:王卓教授数据结构与算法课程PPT截图,适合计算机专业初学者、考研复习者以及需要夯实算法基础的开发者。这份资料将课堂演示文稿核心页面逐页截取,整理为单个PDF文件,整体约102.64MB,便于下载后离线对照学习。内容从数据结构与算法的重要性讲起,涵盖绪论中的数据元素、数据项、逻辑结构与物理结构,以及数据类型与抽象数据类型的区别;随后系统说明算法的定义、程序关系和时间效率度量方法。进入线性表章节后,重点讲解顺序表示和链式表示的实现方式,并通过案例引入加深理解,包括顺序表基本操作、链表表示与定义等内容。完整文件还包含栈、队列、树、图,以及排序和搜索算法的分析,覆盖本科课程主要考点。目前已有4531人浏览学习,可作为课前预习、课堂同步笔记、期末复习和考研资料使用,帮助快速搭建知识体系。
1. 青岛大学王卓数据结构与算法课程PPT截图:为什么它比二刷视频更值得收藏
数据结构与算法这门课,考研党绕不开,408考生躲不掉,期末突击也得靠它。青岛大学王卓老师的《数据结构与算法》课程,在B站是无数人的启蒙资源,而这套课程PPT截图,正是把严蔚敏《数据结构(C语言版)》里那些抽象概念拆成了几百张图解页面——顺序表怎么挪、KMP的next数组怎么跳、平衡二叉树怎么转,看一眼图往往比干啃两小时教材管用。它适合三类人:正在跟课复习的学生、年底冲刺数据结构期末考的人,以及想快速检索算法结论的从业者。我自己也拿它做过考前突击,今天把用法和坑一次讲透。
2. 线性表与KMP算法:怎么把PPT图解变成能跑的代码
2.1 顺序表和链表的结构图:先分清逻辑结构与物理结构
王卓老师的PPT在讲线性表时,最经典的就是那几张存储结构示意图:顺序表画成一串连续格子,链表画成方格加箭头。很多初学者看完觉得“这不就是数组和指针吗”,真上手用C语言写链表时,头节点到底建不建、插入删除怎么改指针,立刻卡住。问题不在代码能力,而在没把图里的“逻辑相邻”和“物理相邻”分清楚。
我一般会在截图旁边做两个标注:逻辑相邻用虚线连,物理相邻用实线连。顺序表两种相邻关系重合,所以随机访问直接按下标算地址;链表逻辑上相邻、物理上不一定相邻,所以增删只改指针,但访问必须从头走。这张表我建议自己抄一遍:
| 操作 | 顺序表 | 链表 |
|---|---|---|
| 随机访问 | O(1),按下标算地址 | O(n),只能从头遍历 |
| 头部插入 | O(n),元素整体后移 | O(1),改头指针 |
| 中间插入 | O(n),先挪位置 | O(1),前提是已定位 |
| 扩容 | 需要重新分配内存 | 不需要,节点随时分配 |
选型理由就藏在复杂度里:读多写少用顺序表,写多读少用链表。408真题里常考的“稀疏多项式存储”选链表,就是因为多项式长度不确定且频繁插入。
2.2 KMP算法:next数组的下标体系是最大的坑
KMP是数据结构里公认的硬骨头,王卓老师的PPT用动画和手写推导讲主串指针不回溯的过程,截图里那几页“失配时模式串滑到哪”非常直观。但PPT不会告诉你,next数组在不同教材里有两种下标体系,这是考研和面试里最容易被绕进去的地方。
严蔚敏教材和大部分考研资料采用next[1] = 0、next[2] = 1的写法,数组下标从1开始;另一派用next[0] = -1,下标从0开始。两种写法算出来的next值不一样,但核心思想相同。王卓老师的课基于严蔚敏教材体系,我建议考研的同学直接按目标院校指定教材来,别混着背。求next数组的代码,我一般这样写:
// 计算模式串 t 的 next 数组(考研体系:next[1] = 0) // t[0] 存模式串长度,t[1] 开始存字符 void get_next(char t[], int next[]) { int i = 1, j = 0; next[1] = 0; // 首字符失配时,模式串整体右移一位 while (i < t[0]) { if (j == 0 || t[i] == t[j]) { ++i; ++j; next[i] = j; // 当前位置匹配,前后缀长度加1 } else { j = next[j]; // 不匹配,j 回退到已匹配的前缀位置 } } }逻辑说明:这里i和j都是模式串的指针,i指向当前要计算next的位置,j指向已匹配前缀的下一个字符。j回退到next[j]是KMP的精髓,它利用前面已经算好的next值,避免暴力回溯。参数说明:t[0]存串长是严蔚敏教材的习惯写法,如果你用的编译器不支持这种“牺牲第一个字符存长度”的方式,可以把t[0]改成单独传入的len参数。改进版nextval需要在t[i] == t[j]时继续判断t[next[j]]是否等于t[i],减少无意义回退,这个在408真题里也出现过。
2.3 栈、队列与双端队列:受限线性表的三种变体
栈和队列本质上都是线性表,只是操作受限。PPT上通常用一竖一横的图来区分:栈只在栈顶插入删除,队列在队尾插入、队头删除。初学最容易搞混的是栈顶方向和队列的判空判满条件,尤其是循环队列,判断队满用(rear + 1) % MaxSize == front,而不是rear == front,后者是“空”的条件。
双端队列是近几年考试的热点,题目常给“输出受限的双端队列”让你判断某个输出序列是否合法。我的口诀是:栈是单口进出,双端队列是两端都能进、但输出端受限,最好在草稿纸上模拟两端操作,不要盯着PPT硬想。循环队列的入队操作我一般会在截图旁边补一段:
// 循环队列入队:先判满,再存元素,最后移动队尾指针 int EnQueue(int queue[], int front, int &rear, int x, int maxSize) { if ((rear + 1) % maxSize == front) { return 0; // 队满,不能入队 } queue[rear] = x; rear = (rear + 1) % maxSize; // 队尾指针循环后移 return 1; }参数说明:front指向队头元素,rear指向队尾的下一个空位,牺牲一个存储单元来区分空和满。这个写法比设置tag标志位更常用,408考试也默认这个方案。双端队列的题目,本质就是在这个基础上放开一侧限制。
2.4 复杂度分析:为什么比背代码更重要
暴力枚举算法和KMP的差距,PPT里用一张对比曲线就能看出来:朴素匹配是O(n*m),两个串长度一大就爆炸;KMP是O(m+n),只扫描一遍主串。很多同学背下了KMP代码,但问他为什么比暴力快,答不上来,这就是没吃透复杂度。复杂度分析是数据结构的“验收标准”,所有算法题讨论的是要不要剪枝、怎么剪,本质上都是复杂度博弈。
剪枝算法在DFS回溯里特别典型,比如N皇后问题,暴力枚举所有棋盘布局是O(2^n)级别,加一行“当前列和对角线是否冲突”的判断,能把大量分支直接砍掉。王卓老师PPT里讲递归和回溯时,那些剪枝示意图值得反复看,它们是理解“暴力到优化”这条路径的最佳素材。
3. 树与图:在截图上做二次标注,把遍历和存储彻底吃透
3.1 树的遍历:递归序是理解前中后序的一把钥匙
二叉树的前序、中序、后序,很多人的记忆方式是“根在前/中/后”,但一遇到非递归遍历就露馅。王卓老师的PPT在讲遍历时,会画递归调用栈的展开图,那几页截图是整个课程里含金量最高的部分之一。关键要理解一个概念:递归序,每个节点在递归过程中会被访问三次,前中后序只是决定在哪一次打印。
// 中序遍历:递归序中第二次到达节点时打印 void InOrder(BiTree T) { if (T != NULL) { InOrder(T->lchild); // 先走左子树 visit(T); // 左子树返回后打印根节点 InOrder(T->rchild); // 再走右子树 } }逻辑说明:visit的位置决定了遍历顺序,放在两次递归调用之间就是中序,放在两次调用之前就是前序,放在之后就是后序。参数说明:BiTree是二叉树节点指针,visit可以替换成任意对节点的操作。我建议在PPT截图上用红蓝绿三种颜色分别标出第一次、第二次、第三次到达节点的位置,这样三种遍历的关系一眼就能看出来。非递归遍历就是在模拟这个递归调用栈,理解了递归序,非递归只是把系统栈换成手动栈。
3.2 平衡二叉树的旋转:LL、RR、LR、RL的判定口诀
平衡二叉树这节课,王卓老师PPT上那四张旋转示意图,是全网流传最广的版本之一。左左型右旋、右右型左旋、左右型先左旋再右旋、右左型先右旋再左旋,每张图都画了子树重链的过程。四张图截下来就能当公式表用,比翻王道或大话数据结构更快。
判定方法我总结为三步:先找第一个失衡节点,再看插入节点在失衡节点的哪一侧,最后看再往下走一层的方向。两个方向一致就是LL或RR,不一致就是LR或RL。常见的错误是只旋转失衡节点本身,忘了它的子树也要跟着调整。做旋转练习时,把PPT上的图抄到草稿纸上,然后遮住答案自己重画一遍,画错的地方就是理解漏洞。
3.3 图的存储:邻接矩阵与邻接表怎么选
图的存储结构是408常考知识点,王卓老师的PPT对邻接矩阵和邻接表的对比讲得很细。邻接矩阵用二维数组存边关系,判断两点是否相邻是O(1),但空间永远是O(n²);邻接表用链表存每个顶点的邻居,空间是O(n+e),但判断相邻需要遍历链表。具体怎么选,我一般按这张表来判断:
| 对比维度 | 邻接矩阵 | 邻接表 |
|---|---|---|
| 空间消耗 | O(n²),与边数无关 | O(n+e),稀疏图省空间 |
| 判断两点相邻 | O(1) | O(degree),度越大越慢 |
| 遍历某点的邻居 | O(n) | O(degree) |
| 适用场景 | 稠密图、需要频繁判相邻 | 稀疏图、频繁遍历邻居 |
还有一个容易被忽略的点:无向图的邻接矩阵是对称矩阵,可以压缩到一维数组存下三角,这是“数据结构408图和数组”结合的典型考点。反过来,邻接表存无向图时每条边存两次,算边数要除以2,很多人在这里丢分。
3.4 图的遍历与最短路径:从DFS/BFS到Dijkstra的复杂度边界
图的DFS和BFS复杂度取决于存储结构:邻接矩阵版是O(n²),邻接表版是O(n+e)。PPT上通常会画两种遍历的访问顺序图,但代码还是要自己写一遍。BFS用队列,DFS用递归或栈,这个选型理由很简单:先访问的节点要先扩展邻居,所以BFS需要FIFO的队列;DFS要走到底再回头,所以用栈或递归天然匹配。
// BFS 遍历邻接矩阵存储的图 // visited[] 防止重复访问,queue[] 模拟队列 void BFS(MGraph G, int v) { int visited[MAXV] = {0}; int queue[MAXV], front = 0, rear = 0; visited[v] = 1; queue[rear++] = v; // 起点入队 while (front != rear) { int u = queue[front++]; // 出队一个顶点 for (int w = 0; w < G.n; w++) { if (G.edges[u][w] && !visited[w]) { visited[w] = 1; queue[rear++] = w; // 未被访问的邻居入队 } } } }参数说明:MGraph是邻接矩阵结构体,edges[u][w]非0表示u到w有边,n是顶点数。BFS保证按层访问,适合求无权图的最短路径。Dijkstra算法解决带权图的最短路径,核心是贪心选当前距离最小的未访问顶点,复杂度用邻接矩阵是O(n²),配堆优化后能降到O((n+e)logn),这在考研题里是个常见的优化追问。
4. 排序与查找:从PPT结论表反推代码边界条件
4.1 十大排序的复杂度对照表
排序章节是数据结构里最应试的部分,王卓老师PPT最后会给一张汇总表,把各种排序算法的时间、空间、稳定性列全。这张表建议保存下来,每次做题前先扫一眼。408和考研数据结构里,快速排序、堆排序、归并排序是考查重点,直接背结论容易翻车,最好能对着PPT上的图示理解每一趟的交换过程。
| 排序算法 | 最好时间 | 平均时间 | 最坏时间 | 空间 | 稳定性 |
|---|---|---|---|---|---|
| 冒泡排序 | O(n) | O(n²) | O(n²) | O(1) | 稳定 |
| 简单选择 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |
| 直接插入 | O(n) | O(n²) | O(n²) | O(1) | 稳定 |
| 希尔排序 | O(n^1.3) | 不确定 | O(n²) | O(1) | 不稳定 |
| 快速排序 | O(nlogn) | O(nlogn) | O(n²) | O(logn) | 不稳定 |
| 堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
| 归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 |
这张表值得记住的规律:稳定的排序只有冒泡、插入、归并、基数;空间开销最大的是归并排序;快排平均最快但最坏退化到O(n²)。选择题里问“哪个排序不可能出现在第k趟后前k个元素有序”这类问题,本质都在考这些细节。
4.2 快速排序的partition边界:一个让无数人翻车的细节
快排的核心是partition,PPT上通常画的是“双向扫描”版:基准元素放中间,左边都小于它,右边都大于它。但双向扫描版边界条件特别容易写错,我一般建议大家先用Lomuto单向扫描版写出正确代码,再去看双向版:
// 快速排序 partition:Lomuto 单向扫描版 // 选择最后一个元素作为基准,比基准小的依次交换到左侧 int partition(int a[], int low, int high) { int pivot = a[high]; // 基准元素 int i = low - 1; // i 指向已处理区间的最后一个位置 for (int j = low; j < high; j++) { if (a[j] < pivot) { i++; int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } // 把基准换到 i+1,这样左边都小于基准,右边都大于等于基准 int tmp = a[i + 1]; a[i + 1] = a[high]; a[high] = tmp; return i + 1; // 返回基准最终位置 }边界说明:循环条件j < high不取等,因为a[high]本身就是基准,不需要和自己比较;i从low - 1开始,保证第一个小于基准的元素能放到正确位置。这里容易错的点:如果数组里所有元素都小于基准,最后返回i + 1正好是high位置;如果有元素等于基准,会被分到右侧,不影响排序正确性但影响稳定性。快排的稳定性答案是“不稳定”,正因为partition交换时可能改变相等元素的相对顺序。
4.3 二分查找:左闭右闭和左闭右开的死循环陷阱
二分查找看似简单,但考研和面试里丢分最多的恰恰是它。核心区别在区间定义:左闭右闭[l, r]和左闭右开[l, r)的循环条件、边界更新方式完全不同。我一直用左闭右闭写法,因为它和C语言的数组下标习惯一致:
// 二分查找:左闭右闭区间写法 // 找到返回下标,找不到返回 -1 int binarySearch(int a[], int n, int key) { int l = 0, r = n - 1; // 区间 [l, r],包含两端 while (l <= r) { // 区间不为空的条件是 l <= r int mid = l + (r - l) / 2; // 防止 l + r 溢出 if (a[mid] == key) { return mid; } else if (a[mid] < key) { l = mid + 1; // 目标在右半区,l 移到 mid 右侧 } else { r = mid - 1; // 目标在左半区,r 移到 mid 左侧 } } return -1; }踩坑点:循环条件写成l < r的话,当l == r且a[l] == key时会漏掉答案;mid计算使用l + (r - l) / 2,避免直接(l + r) / 2在极端情况下整型溢出的问题。算法流程图在教材上画得很多,但考试里要求手写代码时,这些边界细节才是真正拉开差距的地方。
4.4 哈希查找:冲突处理的两种主流方案
哈希表查找先算哈希地址,再处理冲突。PPT上会画两种冲突处理图:开放定址法的线性探测,以及链地址法的拉链结构。考研常考的是这两种的对比,以及平均查找长度的计算。线性探测有个“堆积”现象:冲突元素连续占位,导致后续元素更容易冲突;链地址法则没有这个问题,但指针有额外空间开销。
装载因子a = n / m是哈希表性能的关键参数,a越大,冲突概率越高。在C语言课程设计里,我一般用链地址法,因为它在a较大时依然能保持接近O(1)的查找,而线性探测在表快满时可能退化到O(n)。
4.5 算法设计思想:枚举、剪枝、分治在PPT例题里的位置
王卓老师的PPT虽然不是专门讲算法竞赛的,但最后几个章节会涉及算法设计思想:暴力枚举算法、剪枝算法、分治法。这些思想是蓝桥杯和面试算法题的基础,比如蓝桥杯的填空题,很多第一反应就是两层循环暴力枚举加剪枝优化。理解这些思想最好的方式不是背题,而是把PPT上每道例题的“普通写法”和“优化写法”对照着看,找出优化点到底加了什么约束。
5. 避坑:用PPT截图自学数据结构的5个常见翻车点
5.1 只看截图不写代码:“看懂错觉”最坑
现象:把PPT截图从头到尾翻一遍,觉得每个知识点都懂了,合上截图做题或者写代码,发现无从下手。
原因:数据结构是实践学科,PPT截图只是骨架,代码逻辑需要自己写一遍才能内化。看懂示意图和能写出来的差距,比想象中大得多。
解决:每看完一个章节的截图,强制自己默写一段核心代码。顺序表看完写插入删除,KMP看完写get_next,二叉树看完写中序遍历,写不出来就回看截图,看完再写。三个回合内能独立写出,才算真正掌握。
5.2 拿截图当完整讲义:缺少视频里的推导过程
现象:直接看PPT截图,跳过课程视频,有些章节觉得跳跃,比如KMP的主串指针不回溯为什么成立,截图只有最终结论。
原因:PPT截图是教学的辅助材料,王卓老师很多推导是在视频里手写板书的,截图只有静态结果。
解决:困难章节先看视频理解推导,再用截图做复习存档。视频两倍速,截图用于快速回查,两种配合效率最高。完全不懂的地方不要硬啃截图,该看视频还是看视频。
5.3 混用不同教材的符号体系:next数组的0/1之争
现象:今天看王卓老师的截图,明天翻王道的书,后天查大话数据结构,发现next数组的值不一样,越看越乱。
原因:不同教材对next数组的下标起点约定不同,严蔚敏体系下标从1开始、next[1] = 0,另一种体系下标从0开始、next[0] = -1。两个体系算出来的值不同,但逻辑等价。
解决:选定一个体系学到底。考研的同学以目标院校参考书为准,想快速验证自己写的KMP代码没问题,可以直接用字符串匹配结果来验证,别过度纠结next数组的值本身。
5.4 跳过复杂度分析直接背代码
现象:能默写排序代码,但问“为什么堆排序不稳定”“归并排序为什么空间O(n)”答不上来。
原因:很多人在复习时只盯代码实现,把复杂度当死记硬背的结论,没有从算法操作过程推导复杂度。
解决:每个算法先看PPT上的操作流程,再用流程推复杂度。比如冒泡排序每趟比较相邻元素,n趟就是O(n²);归并排序需要临时数组合并两个有序序列,这个临时数组就是O(n)空间的来源。
5.5 忽视实验报告和机试:期末和面试的隐形杀手
现象:数据结构实验报告能抄就抄,机试的时候发现链表插入都写不对。
原因:期末成绩里实验报告占不少比例,面试手撕代码不给你翻PPT的机会,平时不动手,关键时刻就会翻车。
解决:把PPT截图里的代码当作实验报告的参照,但报告必须自己写。机试练习从“单链表反转”这类基础题开始,每天一道,比考前突击背题管用得多。
6. 把PPT截图变成复习图谱:一个可照做的四列表格整理法
PPT截图最大的问题是零散,几百张图存在网盘里,到用的时候找不到对应的那张。我后来摸索出一个方法:建一个Markdown表格,把每个章节压缩成一行,相当于给截图做索引。表格放在Obsidian或Notion里,手机电脑随时能看,这和做算法工程师面试笔记是一个思路。
| 章节 | 核心问题 | 截图记忆锚点 | 代码骨架 |
|---|---|---|---|
| KMP | 失配时模式串回退到哪 | next数组手写推导图 | get_next + KMP主循环 |
| 二叉树遍历 | 递归序为什么是三种遍历的基础 | 递归调用栈展开图 | InOrder 三行递归 |
| 快排 | partition边界怎么处理 | 基准元素交换示意图 | Lomuto 或 双向扫描版 |
| 堆排序 | 建堆和调整的下标关系 | 完全二叉树数组存储图 | percolateDown 调整 |
整理步骤一共四步。第一步,把全套PPT截图按章节重命名,用两位数字前缀加知识点名词,比如“07_QuickSort_partition边界”,这样排序后就是一份目录。第二步,每学完一章,往表格里加一行,核心问题用一句话概括,比如“快排为什么不稳定”,写不出一句话说明还没吃透。第三步,每周做一次“截图到代码”翻译练习,随机抽三张图,不看书默写对应代码骨架,抽到哈希冲突就写线性探测,抽到图遍历就写BFS。第四步,考前用表格里“代码骨架”一列做默写清单,能默写一个就勾掉一个,比自己翻截图高效得多。
还有个技巧叫“遮答案复现法”:把截图里的最终结论用深色色块盖住,比如KMP的next数组推导结果、快排一趟后的序列,先自己推导一遍,再掀开色块对照。这个习惯能有效防止“看图全会、动手全废”的状态。从那以后,我每次复习数据结构都强制自己先默写代码骨架再去看PPT结论,这个习惯帮我省掉了考前大量返工时间。如果你也在用这份PPT截图复习,建议一套整理到底,别贪多换资料,希望帮到你。
本文还有配套的精品资源,点击获取