尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
数据结构与算法学习笔记:把“看懂”变成“会用”的整理思路
1. 这份笔记到底在记什么很多人问我数据结构与算法这门课到底该怎么学笔记又该怎么记。说实话我见过太多同学的笔记本要么是老师 PPT 的复刻机要么是《算法导论》的浓缩版抄了一堆定义和伪代码合上本子脑子还是一片空白。我自己的定位很明确这份笔记不是教材的搬运工而是把看懂变成会用的转换器。它记录的是我踩过的坑、归纳过的套路、画过的图还有那些当时死活想不通、后来恍然大悟的关键点。如果你正在准备考研 408、刷 LeetCode、应付数据结构实验报告或者单纯想把这门基础课学扎实这份笔记的整理思路应该能帮你少走很多弯路。先交代一下这份笔记覆盖的范围。数据结构部分从线性表、栈、队列、串、树、图到查找和排序基本上是国内教材的标准章节。算法部分除了配套的暴力枚举、递归回溯、剪枝、动态规划、贪心我还额外补充了 KMP、折半查找的典型例题、堆排序的手算模拟、普利姆和克鲁斯卡尔求最小生成树这些高频考点。全程用 C/C 描述偶尔用 Python 验证思路因为考研和期末考的代码题大多以 C 系语言为主而 Python 适合快速验证算法行为和画图看效果。核心原则只有一条每个知识点必须回答三个问题——它解决什么问题它的代价是什么它在什么场景下会被吊打。记不住这三件事背再多代码也是白背。2. 整体设计思路把零散知识串成一张网2.1 为什么不能按目录平铺直叙地记刚入门的时候我也犯过这个错按教材章节老老实实记数组、链表、栈、队列、树……每个章节单独记看起来井井有条实际上毫无关联。学到图的最短路径时突然发现迪杰斯特拉算法和之前学的贪心策略有关学到堆排序时才发现完全二叉树这个老朋友还有这种玩法。这时候回头翻笔记发现前面记的东西跟后面完全连不起来等于白记。后来我把笔记的底层逻辑改成了一条主线物理结构 → 逻辑结构 → 操作效率 → 算法设计策略。不管线性表还是图不管查找还是排序都按这条线梳理。比如数组和链表先看它们在内存里怎么存物理结构再抽象成线性表逻辑结构然后比较插入、删除、查找的时间复杂度操作效率最后落到什么时候用数组、什么时候用链表这个决策问题上。这样每一章都不是孤岛而是同一套思维框架在不同场景下的应用。2.2 笔记的三大支柱图、表、代码我翻了很多高分笔记发现做得好的都有共性图、表、代码三件套齐全。图指的是手绘图解不是截 PPT 图。树的旋转、图的遍历过程、快速排序的分区过程这些动起来才能理解的东西静帧文字很难讲清楚。我习惯用纸笔画一遍再贴到笔记里。比如红黑树的插入修复分了三种情况每种情况左旋右旋怎么转不画图光看文字真的会绕晕。表指的是各类复杂度对比表、适用场景对照表、易混淆概念辨析表。比如各排序算法的时间复杂度、空间复杂度、稳定性一张表全看清。查找算法里顺序查找、折半查找、分块查找的对比树和图里各种遍历方式的对比都适合用表格来沉淀。代码不是抄完整实现而是记录骨架 关键边界条件。完整代码教材和网上都有笔记里只需要留核心逻辑和最容易出错的那几行比如 KMP 的 next 数组求法、归并排序的 merge 边界、链表的头插尾插指针变换。这样复习的时候一眼就能抓住重点不需要重新读一遍几百行的完整代码。2.3 章节之间的关联怎么记我在笔记每个章节开头会留一个小区域叫本章与前文的接口。学树的时候我会提一句树是递归结构的天然载体前面的栈可以实现递归转非递归学图的时候我会标注图的深度优先遍历基于栈的思想和树的先序遍历是同一套逻辑广度优先遍历基于队列和树的层序遍历对应。这些连接点看起来不起眼但正是它们把零散的知识织成了网后期复习效率会高很多。3. 核心细节解析从操作到原理3.1 带头节点和不带头节点的链表到底差在哪这是很多初学者绕不过去的坎。先给结论带头节点纯粹是为了统一操作逻辑省掉对空表和首元节点的特殊判断。想象一下不带头节点的单链表要在第一个位置插入节点你得修改头指针函数里得写if (p head) head newNode;这种分支。而如果有一个头节点data 域不用只当哨兵无论插哪里都是找到前驱节点改它的 next这一个套路不需要判断是不是插在第一个。删除同理带头节点的链表删除第一个有效节点和不带头节点的逻辑完全一致都是改前驱的 next而如果不带头节点删除第一个节点也要特殊处理头指针。我用一张对照表沉淀了这个问题场景不带头节点带头节点空表判断head NULLhead-next NULL头插法需修改头指针只需在哨兵后插入删除首元节点需修改头指针只需修改哨兵的 next循环遍历终止条件p ! NULLp ! head循环链表时考研和期末考试特别喜欢考这个对比考的不是你能不能写代码而是你知不知道为什么。这就是笔记里要重点记录的东西。3.2 栈和队列两个工具人的自我修养栈和队列本身并不复杂但它们是后面很多算法的基石。我在笔记里给它们起了个外号叫操作受限的线性表这样理解起来特别快它们本质还是线性表只不过栈只允许在一端插入删除后进先出队列只允许一端插一端删先进先出。很多人不理解为什么要有这种限制。我的理解是限制操作恰恰是它们的价值所在。栈天然适合嵌套结构的问题比如函数调用、括号匹配、表达式求值队列天然适合公平排队的问题比如任务调度、树的层序遍历、图的广度优先遍历。笔记里我记得最认真的一个点是循环队列的判空和判满。因为顺序实现的队列如果用完整个数组会有假溢出问题所以用取模运算让队尾绕回开头。但这样一来判空是front rear判满也是front rear就矛盾了。常规解法是牺牲一个存储单元让队满条件变成(rear 1) % MaxSize front这样队列最多只能存 MaxSize-1 个元素。这个为什么少一个格子的问题几乎每年都有同学在群里问。3.3 递归与非递归的互相转换递归是树的天然伴侣因为树本身就是递归定义的。但考试和面试常常要求你写出非递归版本这背后其实是手动维护栈的思想。以二叉树的中序遍历为例递归版本极其简单void inorder(TreeNode* root) { if (!root) return; inorder(root-left); visit(root); inorder(root-right); }非递归版本就是自己用一个栈模拟系统栈void inorder(TreeNode* root) { stackTreeNode* st; TreeNode* cur root; while (cur || !st.empty()) { while (cur) { st.push(cur); cur cur-left; } cur st.top(); st.pop(); visit(cur); cur cur-right; } }这里的关键理解是递归版本里系统帮你记住了每个节点的返回地址和局部状态非递归版本就是你亲自把这些状态压栈。我在笔记里画了一张访问路径图用箭头标出每个节点入栈和出栈的时机这个图我建议每个人都要亲手画一遍画完中序遍历非递归就再也忘不掉了。4. 核心算法的笔记怎么记才有效4.1 排序算法不能只背代码要背过程图排序是数据结构里最热闹的一块冒泡、选择、插入、希尔、归并、快排、堆排七种经典算法够喝一壶。我的经验是不要死记代码要把每一趟排序的结果都写出来。是的每一趟。因为考试最爱考的就是给一个序列写出第三趟冒泡排序后的结果或者给一个序列写出快速排序第一趟划分的结果。这类题如果只看过代码没手算过考场上就慌了。比如快排第一趟划分初始序列49 38 65 97 76 13 27 以49为基准low从左边找比49大的high从右边找比49小的 第一趟结果27 38 13 49 76 97 65这个挖坑填数的过程我建议在笔记里画六步左右的快照标出 low 和 high 指针的移动方向这是理解快排本质最快的路径。堆排序则是另一个重灾区。建堆、调整每一轮交换是什么状态必须完全模拟一遍。大根堆自调整因为只能是文字描述。我笔记里记了一个口诀建堆从下往上调排序从上往下换。建堆是从最后一个非叶节点开始往前逐个调整保证每个子树都是堆排序时把堆顶和最后一个元素交换堆规模减一再从上往下调整恢复堆。这两句话能解决大部分堆排序过程搞不清的问题。4.2 查找算法重点永远在比较次数查找这一章的核心考点就是折半查找。折半查找的前提是有序表优点是查找效率高缺点是不适合链表结构因为需要随机访问。笔记里必记的是它的判定树——把每次比较的中间位置画成一棵二叉树这样查找任意元素最多比较多少次一目了然。例题要好好分析这个序列有序序列7 10 13 16 19 29 32 33 37 41 43查找 37 的过程判定树的路径是先和 29 比mid 指向第 6 个元素再和 37 比mid 指向第 9 个元素命中。总共比较 2 次。而如果查一个序列中不存在的元素比如查 30就要一路比到叶子节点的空指针。折半查找的时间复杂度是 O(log₂n)但这是随机访问前提下的结论链表上做折半查找没有意义。ASL平均查找长度的计算也是高频题。成功情况下的 ASL 等于判定树中所有内部节点的层数求和除以节点数失败情况下的 ASL 等于所有外部节点的层数求和除以外部节点数。这个要分清考试经常在这里抖机灵。4.3 KMP 算法next 数组到底怎么求KMP 是串这一章最劝退的知识点但一旦搞懂 next 数组的本质它就再也不会成为难点。next[i] 的含义是当模式串第 i 位失配时i 指针应该回退到的位置或者等价地说是模式串前 i-1 位中最长相等前后缀的长度加 1。求 next 数组我推荐用递推的方式理解// 模式串 t 的 next 数组求法j 表示当前已匹配长度 int next[MAXN]; next[0] -1; // 哨兵方便判失配 int i 0, j -1; while (i t.length()) { if (j -1 || t[i] t[j]) { i; j; next[i] j; } else { j next[j]; } }笔记里必须手算一遍。以ABABABB为例逐个求 next 值。这个过程中最难理解的是失配时j next[j]这行代码——它其实在用已匹配部分的最长相等前后缀来减少无谓的比较。我的技巧是把它和暴力匹配算法对比着看暴力匹配失配时主串指针回溯到本次起始位置的下一个KMP 则保持主串指针不回溯只让模式串指针跳转这就是 KMP 比暴力算法快的原因。4.4 图从遍历到最短路径的层层递进图这一章是数据结构里信息密度最大的考试分值也高。我的笔记思路分四层组织第一层是存储结构邻接矩阵和邻接表必须对比记。邻接矩阵适合稠密图判断任意两个顶点是否相邻是 O(1)邻接表节省空间但判断相邻关系要遍历链表最坏 O(n)。从顶点找邻边邻接表完胜判断两顶点是否相连邻接矩阵完胜。这几个结论要能脱口而出。第二层是遍历深度优先DFS和广度优先BFS一定要记住它们的辅助结构DFS 用栈或递归BFS 用队列。遍历序列的生成过程务必在笔记中画出模拟步骤。值得注意的是图的连通分量个数可以通过 DFS 或 BFS 的次数来统计——每启动一次遍历就说明发现了一个新的连通分量。第三层是最短路径。迪杰斯特拉算法单源最短路径是贪心思想的典型应用每轮选一个离源点最近且未被访问的点然后松弛它的邻居。弗洛伊德算法全源最短路径是动态规划三重循环d[i][j] min(d[i][j], d[i][k]d[k][j])。笔记里要强调迪杰斯特拉不能处理负权边弗洛伊德可以只要没有负权环。这个考点几乎每年都会以选择题或简答题的形式出现。第四层是生成树。普利姆算法从一个顶点出发每次选已经在树中的点到不在树中的点的最短边适合稠密图克鲁斯卡尔算法把所有边按权排序从小到大选不构成环的边适合稀疏图。而判断是否构成环用的是并查集这又是一个跨章节的知识点我在笔记里把它们串在一起记。4.5 经典算法思路剪枝、贪心与动态规划的边界算法策略这块我在笔记里分了三个典型家族回溯算法的核心是尝试-撤销。N 皇后、全排列、组合求和都是这个套路。剪枝是回溯的加速器本质上就是提前判断这条路继续走也不会产生合法解直接放弃。比如组合求和问题里如果当前和已经超过 target就没必要继续递归了这就是最简单的剪枝。我在笔记里记了一个通用框架void backtrack(当前状态) { if (当前状态是合法解) { 记录解; return; } for (每个可选操作) { 做选择; backtrack(新状态); 撤销选择; } }这个框架能解一大片回溯类题目但要注意剪枝条件通常要写在 for 循环里面做选择之前先判断而不是等到递归进去再判断否则递归层数会白白增加。动态规划和贪心的区别我用一句话总结贪心是每一步做当前看起来最优的选择不回头动态规划是枚举所有可能的子问题择优保留。贪心的经典例子是活动选择问题、哈夫曼编码动态规划的经典例子是 0-1 背包、最长公共子序列。做动态规划题笔记里一定要写清楚状态定义和状态转移方程这两个东西写清楚了代码就是翻译的事。5. 实验报告与上机实操笔记怎么反哺代码5.1 从笔记到代码三步走很多同学笔记记得很漂亮一到写代码就卡壳。我的方法是从笔记提炼一个代码撰写三步走第一步把笔记里的算法思路画成流程图。图不用画得很正式关键是标注清楚循环条件和退出条件特别是边界情况空表、单节点、满队列。第二步把流程图里的每个节点翻译成代码骨架。这一步不要追求一次写对先写主逻辑把边界情况留到第二步。第三步对着笔记里的易错点清单逐一检查。我笔记里常驻的清单包括单链表的指针顺序先接后面再接前面、树的递归终止条件空指针判断、快排的区间划分left right 才递归、KMP 的 next 数组初始化。5.2 实验报告怎么写才能得高分数据结构实验报告是很多学校的硬性要求但大多数同学写成了代码粘贴板。我的经验是报告的重点应该在设计思路和结果分析上。设计思路部分要写清楚你选择了哪种数据结构、为什么选它、时间复杂度是多少、有没有考虑过替代方案。比如图书管理系统你用顺序表而不用链表理由可以是访问频繁、很少插入删除顺序表能发挥随机访问优势。结果分析部分要贴运行截图并给出分析输入什么数据、输出什么结果、正确性如何验证、性能是否符合预期。特别建议做一个测试用例表把普通用例、边界用例空表、满表、重复数据都覆盖到老师一看就知道你认真测过了。还有一个万人踩的坑实验报告里严禁大段贴代码。除非老师明确要求否则贴核心代码片段比如关键数据结构和核心算法就够了要贴的是提炼过的精华不是整份 main.cpp。我见过太多实验报告二十页纸有十八页是代码剩下的两页是运行截图这种报告本质上等于没写设计、没写分析。5.3 Python 验证思路C 完成交付我的习惯是复杂算法先用 Python 快速验证再用 C 写出正式代码。原因很简单Python 写起来快、调试容易、可视化方便特别适合验证这个思路到底对不对。而 C 的优势在于贴近底层、指针操作直观、考研和刷题平台都认。比如写 A* 算法我先用 Python 把启发式搜索的逻辑跑通把每一步 open list 和 closed list 的变化打印出来确认路径没问题之后再用 C 重写。两个语言的差异点集中在手动内存管理和 STL 使用上这样的对照还能加深对语言本身特性的理解。6. 常见问题与考场避坑实录6.1 为什么我的快排死循环了这是排序代码里最经典的问题。快排的 partition 函数如果写得不严谨在遇到重复元素或区间只有一个元素时可能出现无限递归或数组越界。我自己的版本是这么写的注意 while 循环里的边界条件int partition(int a[], int low, int high) { int pivot a[low]; while (low high) { while (low high a[high] pivot) high--; a[low] a[high]; while (low high a[low] pivot) low; a[high] a[low]; } a[low] pivot; return low; }易错点有两个。第一内层 while 必须加low high条件否则 high 可能一路减到数组左端之外访问越界。第二为什么等于 pivot 的元素也要跳过如果不跳遇到全部相等的数组时两个指针会反复交换虽然不会死循环但会造成大量无效操作效率退化到近似 O(n²)。如果是极端重复元素的场景可以换用三路快排但考试和竞赛一般不至于这么卷。6.2 树的递归遍历传参传引用还是传值这是一个特别容易在 C 里翻车的问题。递归遍历树的节点计数函数如果写成void count(TreeNode* root, int cnt)cnt 传的是值拷贝每个递归层都在修改自己那一份副本回到上一层就丢了。正确写法是传引用void count(TreeNode* root, int cnt)或者返回 int 值层层累加int count(TreeNode* root) { if (!root) return 0; return 1 count(root-left) count(root-right); }这个坑看着低级但我见过不止一个同学在考场或面试中翻车。笔记里最好把这个现象标注成经典 C 误区递归计数必须是返回值累加或引用传参。6.3 面试和考试里那些口头算法题很多算法不是让你写完整代码而是讲思路。这时候笔记里的场景-算法映射表就派上用场了。我整理过一张速查表这里分享核心部分问题特征首选思路预备思路找数组中第 K 大/小的数快速选择快排 partition堆维护前 K 个求连续子数组最大和动态规划Kadane前缀和 最小前缀判断链表是否有环快慢指针哈希表记录地址两个有序数组合并归并双指针从后往前覆盖字符串匹配KMP朴素匹配短串网格/迷宫最短路径BFSA* 启发式搜索找下一个更高身高的小朋友单调栈暴力枚举不推荐区间调度最多活动数贪心按结束时间排序动态规划这张表的价值在于看到问题特征就能第一时间锁定算法方向而不是现场瞎试。我特别想强调的是单调栈这个工具它看起来冷门但下一个更大元素每日温度接雨水这些经典题全是它的主场笔试面试出现频率极高。笔记里单独给它开了一节单调栈维护的是从栈底到栈顶单调递减/递增的序列新元素入栈前所有栈顶能它弹出的元素都能确定它们右边第一个比它大/小的元素这个思想一旦理解一堆题就通了。6.4 期末复习的黄金七天安排如果你只剩一周准备期末考试我的建议是前四天按章节刷笔记的图和表后三天直接刷真题和小题。具体安排是这样的第一天线性表 栈 队列。重点复习链表的各种操作、循环队列判满判空、中缀转后缀表达式。 第二天树和二叉树。遍历序列互推、哈夫曼树、二叉排序树和平衡树的概念。 第三天图。邻接矩阵/邻接表、DFS/BFS 序列、迪杰斯特拉手算、普利姆/克鲁斯卡尔手算。 第四天查找 排序。折半查找判定树、ASL 计算、快排和堆排的手算过程。 第五到七天做真题。每套真题做完把错题对应的知识点回笔记里大圈标记考前只看大圈的部分。这个安排的核心逻辑是数据结构期末考试的难点基本都集中在手算过程上不太会考你现场写一个跳表之类的高级内容。所以笔记中带图的章节都是复习的重点不要眼高手低。7. 几个我反复强调的经验第一笔记一定要有自己的图。教材上的图是别人的理解你亲手画的才是你自己的。画图的过程本质上是模拟算法执行的过程这个模拟做过一遍比背十遍文字都管用。第二复杂度分析不能只记结论要会推导。比如堆排序为什么是 O(n log n)建堆需要 O(n)从下往上调整大部分元素只在很浅的层移动但 n 次堆调整每次是 O(log n)所以整体是 O(n log n)。记推导过程才能在考试中灵活应对变体题。第三算法之间是会串门的。优先级队列用堆实现图的迪杰斯特拉用优先级队列优化最小生成树的克鲁斯卡尔用并查集判环哈夫曼编码也是贪心。笔记里这些跨章节的连接点正是考试中综合题的出题源泉。不要孤立地学每一章人为制造知识割裂。第四也是最重要的一条这份笔记不是用来收藏的是用来反复翻、反复改的。我每次刷完新题都会回笔记里补充一个变体或者标注一个新的易错点。半年下来笔记会比最初厚一倍但那才是它真正值钱的样子。我在实际使用中还有一个受益颇多的习惯每周日晚会抽出半小时把这周刷题或者复习中遇到的错误集中誊一份到笔记前面给每一条标注上我为什么当初会这么想。这个习惯坚持三个月之后我发现自己的错误越来越集中大部分都在几类固定误区里打转。把这些误区挨个消灭掉数据结构和算法的基础就真的瓷实了。希望这些经验也能让你的学习笔记真正变成一面墙而不是一摞纸。
RELATED

相关推荐

ERP主数据与业务数据引用关系:从断裂到治理的实战路径

ERP主数据与业务数据引用关系:从断裂到治理的实战路径

简介:这是一份面向ERP实施顾问、企业信息化与主数据管理人员的17页PPTX演示文档,讲解ERP主数据与业务数据的关系,并给出常见问题的解决方案。压缩包内仅含1个PPTX文件,共164KB,内容聚焦;已有44人学习。文档…

📅 2026/10/9 14:15:23
NC57 与 Oracle 10g 安装部署全流程:依赖关系、静默安装与避坑指南

NC57 与 Oracle 10g 安装部署全流程:依赖关系、静默安装与避坑指南

简介:这份文档面向用友NC57的部署实施人员与运维初学者,聚焦Oracle 10g数据库与NC57产品的完整安装流程,帮助读者在较短时间内理清从数据库搭建到系统上线的关键环节。资源包内共1个doc文件,压缩包约2.77MB,以图文步骤…

📅 2026/10/9 14:15:23
古诗文MySQL数据库:结构化诗词诗人数据包,开箱即用

古诗文MySQL数据库:结构化诗词诗人数据包,开箱即用

简介:这是一份面向古典文学研究者、中文专业师生及诗词爱好者的数据资源,提供结构完整、内容详实的诗词诗人MySQL数据库,用于支持古籍数字化分析、教学案例构建与个人学习检索。资源包含3个核心SQL文件,分别定义诗人信息表、诗词元…

📅 2026/10/9 14:15:23
MORE NEWS

更多资讯

📰

面向程序员的数理逻辑精要:形式系统、语义与自动证明

简介:这是一份专为计算机科学专业学生打造的数理逻辑核心考点复习笔记,聚焦形式化推理能力培养,解决课程学习、期末备考与考研基础夯实中的概念抽象、公式结构难理解、归纳证明不熟练等痛点。资源为单文件PDF,共1个869KB的高清笔记…

📰

mangos-tbc 2.4.3 内容数据库 tbc-db 导入配置与自定义修改实战

简介:TBC-DB 是面向 CMaNGOS / mangos-tbc 服务端开发者的内容数据库资源,专为《魔兽世界》2.4.3 客户端(内部版本 8606)打造,解决私服搭建中角色、物品、任务、生物等游戏内容数据的存储与维护问题。数据库以 SQL 文件…

📰

Warp 2.0 从零上手:4 步把终端变成 Agentic 开发环境(GitHub 6.4万星)|TaoToken 统一 Key 接入 MCP 实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

【Claude Code 全攻略】终端 AI 编程助手从入门到进阶:把 settings 改到 TaoToken 的完整配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

我给自己写了一个 mini OpenRouter:基于蓝耘 MaaS 的多模型路由网关实战

我给自己写了一个 mini OpenRouter:基于蓝耘 MaaS 的多模型路由网关实战 一、为什么需要"自己的网关" 前几篇我把蓝耘 MaaS 的 API 已经摸熟了——45 个模型、OpenAI 兼容协议、统一 Key 调用。但真要在生产环境用起来,会很快撞上几个工程问题…

📰

GLM-5.3-Flash 清华智谱重磅发布:320B 参数、18B 激活,性能超越 GLM-5.2 且价格仅十分之一——TaoToken 统一 Key 实测接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬