数据结构C语言版学习指南:核心算法与实战经验详解

发布时间:2026/9/13 13:39:55
数据结构C语言版学习指南:核心算法与实战经验详解 1. 这门课为什么绕不开C语言版我接触《数据结构C语言版》这本教材其实是在大二上学期。当时没觉得它有多特别直到后来面试、考研、做项目回头再看才知道当时啃下来的东西几乎贯穿了整个计算机学习的后半程。今天这篇博文我想以“过来人”的身份把这本书、这篇文章背后浓缩的知识体系、实操方法、常见考法和踩坑经验完整整理一遍。适合正在学数据结构的学生、准备计算机二级或软件设计师考试的朋友、想补基础的自学者甚至是已经在工作但想回头巩固底层能力的开发者。先说结论数据结构是程序的骨架C语言是实现骨架最直接的工具。很多初学者拿着《数据结构C语言版》觉得晦涩不是笨而是没有理解这本书的真正用法。它并不是一本纯粹讲C语言的书也不是一本纯粹讲算法的书它是在教你“用内存逻辑去思考问题”。一旦你接受这个设定整本书的难度至少降一半。我自己复现过这本书里几乎所有代码也帮不少学弟学妹改过错。最大的体会是只要把“结构体 指针 动态内存分配”这三样东西搞明白这本书的核心代码你就能看懂八成。这三个东西恰好也是C语言里最劝退的部分所以很多人其实不是被数据结构难倒的而是被C语言基础给绊住了。接下来我会从课程的整体思路、环境配置、核心代码逐段分析、实验报告写法、课程设计实战、面试考点、错误排查几个维度来展开。这不是一篇简单的知识点罗列而是把我在学习和实战中积攒下来的经验、代码、教训全部放到这里希望对你有实际帮助。2. 课程整体思路与核心设计逻辑2.1 严蔚敏版C语言数据结构到底在讲什么《数据结构C语言版》全书的核心逻辑可以概括为一条线数据结构 数据的逻辑结构 存储结构 基本操作的实现。逻辑结构解决的是“数据元素之间是什么关系”的问题。比如一对一的线性关系是线性表一对多是树多对多是图。存储结构解决的是“这些关系如何在计算机内存里落地”的问题主要就两种一种是顺序存储用一段连续内存一种是链式存储用指针把不连续的节点串起来。基本操作就是增删改查也就是书里各种ADT定义的InitList、ListInsert、ListDelete这些函数。很多人看书喜欢跳过ADT描述部分直接看代码。我建议反过来把每个数据结构前面的ADT描述认真读一遍因为那是这个数据结构的行为约定定义了你能干什么、不能干什么。代码只是这些操作的具体实现不同的存储结构对应不同的实现方式但接口逻辑是一致的。理解了ADT你后面看代码会轻松很多也会明白考研题里那些“设计一个算法实现某功能”的题目到底在考什么。2.2 为什么学习数据结构必须搭配C语言有人会问现在都学Java、Python为什么还要用C语言写数据结构我个人的理解是C语言几乎是唯一一种能让你“看见”内存操作的语言。比如单链表的插入操作本质上就是让新节点的next指向后继节点再让前驱节点的next指向新节点。在Python里这些指针操作被封装得干干净净你不需要管next是谁在Java里虽然有引用但内存分配和回收都有虚拟机帮你处理。只有在C语言里p-next q-next这一步你是清清楚楚地在操作一个地址。这种“看得见摸得着”的感觉对理解数据结构本身非常有帮助。另外C语言版数据结构涉及大量的结构体、指针、动态内存分配这些内容本身就是面试和考试的高频考点。把这本书学好等于同时拿下了C语言指针和数据结构两座大山。等后面学C、Java的数据结构时你会发现思想都是通用的只是语法换了层皮而已。2.3 数组、结构体与指针C语言数据结构的三大基石在啃这本书之前我建议你先自查一下自己的C语言基础特别是以下三点结构体是否理解struct的本质是一段内存的布局模板是否知道typedef struct和struct的区别指针是否知道指针变量存的是地址p-next和(*p).next是否都看得懂动态内存malloc/calloc/realloc/free是否熟练是否知道free之后要置NULL这三个点不熟代码基本看不下去。我见过太多人卡在链表那一章原因不是链表难而是看到 LinkList L (LinkList)malloc(sizeof(LNode)) 就晕了。这一行代码拆开来看其实并不复杂LNode是一个结构体类型sizeof(LNode)是计算出这个结构体占多少字节malloc按这个大小分配一段内存并返回地址把这个地址强制转换成LinkList类型赋值给指针变量L。理解这一行链表的大门就打开了。我个人还有一个建议在正式学数据结构前花一两个周末把C语言的指针和结构体专项练一练用翁恺老师的练习题或者自己找OJ上的简单题都可以。基础补上之后再看严蔚敏版教材你会发现自己看代码的速度提升一个档次。3. 环境准备与开发工具配置3.1 从Code::Blocks到VS Code开发工具怎么选数据结构的学习代码基本不依赖第三方库纯标准C语言就能搞定所以选一个好用的编译器就行。我最早用的是Code::Blocks后来这些年用得最多的其实是VS Code GCC组合。如果你是在Windows上我推荐两个方案方案一直接装Dev-C体积小自带编译器打开就能写非常适合新手跑通第一个链表程序。问题是调试功能比较弱代码提示也一般。方案二VS Code MinGW。这套方案比较现代插件生态好代码高亮和智能提示都不错。配置方法网上很多核心就是两步装好MinGW并把gcc加入系统PATH然后在VS Code里装C/C扩展配置好tasks.json和launch.json就能F5调试了。我目前比较推荐的其实是方案二。因为数据结构后期会涉及比较复杂的内存调试问题VS Code的调试器支持查看指针指向的值、单步跟踪每一步的指针变化这对于理解链表操作太重要了。你在Dev-C里F5进调试也能看但体验确实差点意思。3.2 编译与调试的基本流程写数据结构的代码我建议从第一天就养成“边写边编译边调试”的习惯。具体流程是写一个小函数比如链表的初始化函数先编译确认没有语法错误写主函数调用这个初始化函数编译运行测试输出再写下一个函数重复以上过程。这样做的好处是出错时你能快速定位问题范围而不是写完几百行代码再一次性编译看到几十个报错直接崩溃。调试上我建议最少掌握断点、单步进入Step Into、单步跳过Step Over、监视变量Watch这四个功能。链表操作中每次p p-next执行前在监视窗口里看一眼p、p-next的值很多逻辑错误一眼就能看出来。4. 核心数据结构逐一拆解与C语言实现要点这块是整个博文的主体。我会按照书的大纲把线性表、栈与队列、串、树、图、查找和排序逐个过一遍每一部分不仅讲理论还直接从C语言实现的角度分享我的理解和踩坑。4.1 线性表从数组到链表线性表是最基础也最重要的数据结构因为后续的栈、队列其实都可以看作是受限的线性表。严蔚敏版教材用顺序表和单链表两种存储结构来介绍线性表这个安排非常经典。顺序表数组实现顺序表的本质就是动态数组。核心代码是#define MAXSIZE 100 typedef struct { int data[MAXSIZE]; int length; } SqList;这里的关键操作是插入和删除。插入时要先判断位置是否合法再判断表是否已满然后把从插入位置到表尾的元素依次后移一位最后放入新元素并让length加1。很多初学者会忽略插入位置是从1开始计数的而数组下标是从0开始这里就出现经典的off-by-one错误。我建议参考代码时自己画一个图5个元素在第三个位置插入谁要后移、下标怎么变都画清楚再写代码。单链表单链表的节点定义是typedef struct LNode { int data; struct LNode *next; } LNode, *LinkList;注意这段定义里LNode是结构体名*LinkList是结构体指针的别名。用LinkList声明头指针用LNode声明节点结构体是书上常用的风格。链表最容易错的操作是删除。删除节点p的后继节点正确的做法是先定义一个临时指针q p-next然后让p-next q-next最后free(q)。很多人会写成free(p-next)再p-next p-next-next这就错在free之后再去访问被释放的内存属于典型的野指针问题。虽然有时程序不报错但这是未定义行为在考试和面试中是绝对会被挑出来的毛病。我自己的练习方法比较笨但很有效不看代码用一张纸画链表结构然后试着写出插入、删除的完整函数再对照标准答案逐行检查边界条件。比如链表为空、pos为0、pos等于length等特殊场景写完后手动走一遍流程检查是否有空指针解引用或内存泄漏。这个习惯帮我熬过了后来很多面试手写题。循环链表与双向链表循环链表和双向链表属于线性表的变种。循环链表解决的是“从任意位置出发遍历整个表”的问题双向链表用两个指针域prior和next解决“只能从头往后走”的问题。双向链表的插入删除比单链表更繁琐因为要修改四个指针但有一个好处是删除时不需要知道前驱节点。这些都是考试喜欢出的细节我建议大家画图记忆不要死记代码。4.2 栈与队列受限的线性表栈和队列是应用极为广泛的数据结构C语言实现它们有两个经典的存储方案顺序栈和链栈。顺序栈的核心代码通常长这样typedef struct { int data[MAXSIZE]; int top; } SqStack;top指向栈顶元素的位置。入栈时先判断是否栈满然后top再赋值出栈时先判断是否栈空先取值再top--。这里有一个细节严蔚敏版教材里有些版本top初始化为-1有些版本初始化指向栈底位置判定栈空和栈满的条件就不一样。考试和写代码前先看清楚你自己的实现约定别混用。栈和队列的经典应用包括括号匹配、表达式求值、递归转非递归、BFS中的队列、函数调用栈等。我建议学完栈之后立刻用数组模拟实现一个括号匹配的程序这对理解栈“后进先出”的特性特别有帮助。队列的顺序实现有一个坑就是假溢出问题也就是队尾满了但队首还有空位这时候就得用循环队列靠取模运算让队尾绕回开头。4.3 串从暴力匹配到KMP算法串的学习重点在模式匹配。最朴素的办法是暴力匹配两层循环时间复杂度O(m*n)写起来不难但效率低。而KMP算法是考研和面试的高频考点也是让无数人头疼的难点。KMP的核心是next数组。next数组计算的是“模式串里某个位置之前的前缀和后缀有多长的公共部分”这个数组既可以用递推得到也可以手算。刚开始学的时候我建议先把暴力匹配的代码写熟再去理解KMP的优化思路。因为KMP本身是建立在暴力匹配基础上的它优化的只是“主串指针不回溯”这一点。手算next数组有一个笨办法对于模式串的每个位置看它前面的子串不包含当前字符最长有多大长度的相同前缀和后缀然后加1。例如模式串 “ababc” 的next数组我可以逐个位置推给你看。a前面没有字符next[1]规定为0b前面是a没有前后缀公共部分next[2]1a前面是ab没有公共部分next[3]1b前面是aba有长度为1的公共前后缀anext[4]2c前面是abab有长度为2的公共前后缀abnext[5]3。这个过程熟练之后你再看书上的递推代码就会觉得它在做的其实跟自己手推的逻辑一样。我自己在学KMP时踩过一个坑书的版本不同next数组的定义有细微差别有的next从0开始有的从1开始求next数组的代码也跟着变。考试时如果碰到KMP题目一定要先看清题目用的是哪个版本的next定义再写代码或计算结果否则很容易全盘皆错。4.4 树与二叉树递归思想的训练场树这一章是整个数据结构的重头戏也是面试最爱考的章节之一。二叉树的结构体定义极其经典typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree;前序、中序、后序遍历是基础中的基础。三种遍历的递归版本其实只有一行代码顺序的不同但很多初学者就是背不住。我的记忆方法是前序是“根左右”中序是“左根右”后序是“左右根”这里的“根”指的是根节点的访问时机。学二叉树时有一个非常重要的扩展练习不用递归实现三种遍历。前序用栈可以轻松搞定中序稍复杂一点后序更难需要标记每个节点是否已经访问过右子树。这个练习做完之后你对栈和树的理解都会上一个台阶。二叉树的题目在面试中出现频率极高比如求树的深度、求叶子节点数、判断两棵树是否相同、判断是否平衡二叉树、层序遍历、重建二叉树等。这部分的C语言代码不复杂但我建议一定自己在编译器里敲一遍不要光看。因为树的代码有大量递归看代码是无论如何也体会不到递归栈的流动过程的只有亲手调试观察每一层递归的参数变化才能真正理解递归。4.5 图矩阵与链表的博弈图在严蔚敏版教材里篇幅很大但很多学校的期末考试或考研初试并不会要求实现完整的图算法更常见的考法是选择题、填空题、简答题考察各种概念邻接矩阵、邻接表、DFS、BFS、最小生成树、最短路径等。C语言实现图有两种主流存储方案。邻接矩阵用二维数组逻辑简单判断两点是否相邻是O(1)但稀疏图浪费空间邻接表用数组链表更省空间但实现起来更复杂。我个人的建议是图的存储结构理解即可重点放在算法逻辑上。DFS可以用递归也可以借助栈实现BFS必须借助队列实现这两者的模板代码是面试高频建议背到滚瓜烂熟。最短路径的Dijkstra算法和最小生成树的Prim、Kruskal算法笔试爱考面试也爱问思路。这个阶段不需要手写全部代码但要把贪心策略和步骤说清楚。我自己在复习时会给每个算法画流程图然后在旁边标注数据结构visited数组、dist数组、lowcost数组等效果比单纯看代码好很多。4.6 查找与排序写代码最多的一章查找和排序是最能体现“代码基本功”的章节也是计算机二级、软件设计师、考研和面试的高频命题范围。查找部分需要掌握顺序查找、二分查找、二叉排序树、哈希表。其中二分查找是重中之重也是面试手写题里翻车率很高的题目。二分查找的坑集中在边界条件循环条件是 left right 还是 left right中间值计算是 (left right) / 2 还是 left (right - left) / 2更新边界时是 mid 还是 mid - 1 / mid 1。我强烈建议你把这三种写法都写一遍然后针对数组长度为奇数和偶数的情况手动走一遍彻底搞清楚边界。哈希表部分重点掌握哈希函数设计、冲突处理的两种方法开放定址法和链地址法以及各自的优缺点。考试常出这样的选择题给一组关键字、一个哈希函数和冲突处理方法让你计算每个关键字的地址或者是查找成功/失败时的平均查找长度。这种题一定要动手画表不要干想着心算步骤繁琐但得分率其实很高。排序部分要求更高。以下这些算法的思想、稳定性、时间复杂度和空间复杂度必须无条件记住直接插入排序希尔排序冒泡排序快速排序简单选择排序堆排序归并排序基数排序其中快速排序是整个章节的灵魂。很多人在理解快排时卡在“为什么一趟排序之后pivot左边都小于它右边都大于它”这个问题上。我的解释是快排每一趟的目标就是让pivot找到自己最终的位置这个过程通过两个指针交替扫描和交换完成。你不需要一次记住全部只需要记住low从左往右找比pivot大的high从右往左找比pivot小的找到就交换直到low和high相遇最后把pivot放在相遇位置。堆排序的难点在于建堆和调整堆的过程。我建议先画一个完全二叉树图在图上手动模拟一次大顶堆的建立再把代码对照着写。很多教材直接上代码导致初学者完全看不懂sift函数在干什么其实它做的就是“从某个非叶子节点开始把较大的孩子往上浮”这件事。5. 实验报告与课程设计的实战做法5.1 数据结构实验报告怎么写才不会被批注“空洞”很多学校的实验报告要求包含实验目的、实验内容、算法设计、核心代码、运行结果、问题分析。我见过太多同学直接在网上抄一段代码然后随意截个图交上去这种报告分数基本不会高。我的建议是实验报告应该重点写这三块算法设计画出流程图或者用文字描述你的解决思路说明为什么选择这种存储结构和算法核心代码带了注释关键步骤用文字解释运行截图的旁边标注测试数据是什么、输出结果说明了什么、是否有边界测试。比如实验内容是“实现顺序表的插入和删除”你就可以在报告里写清楚这个函数的时间复杂度为什么是O(n)因为最坏情况下需要移动n个元素然后给出测试用例比如空表插入、表满插入、在头部插入、在尾部插入截图每个用例的输出。这种报告老师看了就知道你是真做了不是抄代码。5.2 课程设计实战植物百科数据的管理与分析系统课程设计是很多同学第一次接触“完整项目”的环节。以热词里提到的“植物百科数据的管理与分析”为例这个题目很适合用来展示数据结构在真实系统中的应用。我的初步设计思路是这样首先是数据读取。植物百科数据通常以文件形式存储比如text.csv每一行代表一条记录包含植物名称、科属、分布地区、药用价值、形态特征等信息。用C语言的文件读写函数fopen/fgets/sscanf进行读取把每条记录包装成一个结构体然后存储到内存中。然后是存储结构选择。如果需要频繁地按编号查找可以选用顺序表按数组存储用二分查找提升效率如果数据量很大且需要频繁插入删除就选择二叉排序树或者链表。我当时做类似项目时数据量不算太大就选择用顺序表做主存储再辅助一个二叉排序树做按名称的快速查找。这样设计能同时体现顺序存储和链式存储的应用也方便答辩时展示。最后是分析与统计模块。核心是排序和查找算法的应用。比如按植物高度排序可以调用快速排序筛选“分布在某省份”的植物用顺序遍历即可统计科属数量分布可以用哈希表做计数。这个课程设计做完基本上就把线性表、树、查找、排序全部串起来了。答辩时老师常问的问题是为什么用顺序表不用链表你的查找时间复杂度是多少数据量大了你的程序还能撑住吗这几个问题如果都能答上来课程设计的高分就稳了。5.3 从课程设计到项目的进阶思考课程设计做完后如果你学有余力可以考虑做两个方向的扩展。第一个方向是从“能跑”升级到“能看”因为纯控制台界面在答辩时确实很难出彩可以加上简单的窗口或网页展示哪怕只是把植物信息的查询结果用可视化方式呈现展示效果也会好很多。第二个方向是数据规模上的升级在程序里生成10万条模拟数据测试各排序算法的耗时然后画一张对比图表这会让你的课程设计比其他同学高一个层次。6. 高频考点、面试题与常见错误排查6.1 数据结构高频核心知识点清单根据我对历年考试和面试题的观察数据结构的高频考点集中在以下板块线性表顺序表与链表的插入删除操作、时间复杂度分析、头插法尾插法栈与队列出入栈序列判断、循环队列判满判空、表达式转换中缀转后缀串KMP算法、next数组计算树二叉树遍历序列求树、根据前序中序求后序、哈夫曼树构建、二叉排序树图DFS/BFS、最小生成树Prim与Kruskal、最短路径Dijkstra查找二分查找的平均查找长度、哈希表冲突处理排序快排、堆排、归并排序的过程模拟与复杂度其中“根据前序遍历和中序遍历求后序遍历”和“给定一组数画出哈夫曼树并求WPL”是笔试里几乎必考的题型你最好保证能完美手写出来。另外后序遍历的非递归实现也是面试手写题中的常见变体值得单独练。6.2 经典C语言代码题与手写题面试和二级考试中常出现的一些C语言代码题我把它们整理成一个清单附上简单解析和建议方便大家自查字符串逆序用双指针从首尾向中间交换字符。注意要处理空串和长度为奇数的边界。判断回文串可以用栈实现先入栈再出栈或直接用双指针原地判断。单链表反转用三指针法pre、cur、next循环改变指针指向。这个题面试概率奇高必须闭眼能写。括号匹配检查遇到左括号入栈遇到右括号出栈并匹配最后检查栈是否为空。数组去重并排序先排序后去重或直接用计数法/哈希表。合并两个有序链表用递归或迭代递归代码简洁但需要注意返回值。二分查找重点在边界条件。快速排序的一趟过程模拟很多笔试不给代码只让你写出一趟排序后的序列状态。关于这几个题我个人认为死记代码没用最好的方式是理解思路后先用中文描述算法步骤然后再翻译成C代码。比如反转链表你在纸上画1-2-3-NULL手动把箭头改成3-2-1-NULL再去看代码里pre、cur、next在每一轮分别指向谁思路一下子通了。6.3 常见错误排查内存问题与逻辑坑数据结构C语言版最常见的问题不是算法不懂而是程序运行时各种崩溃。我总结了几个出现概率最高的错误类型以及对应的排查思路。段错误Segmentation Fault段错误几乎都是指针或内存使用出了问题。常见原因有三种访问了free之后的内存数组下标越界对NULL指针解引用。排查手段也很固定先用printf加日志定位崩溃大概发生的位置或者直接在调试器里跑程序崩了之后看调用栈基本能定位到具体某一行。我举个例子假如你写了这样一个链表遍历循环while (p ! NULL) { printf(%d , p-data); p p-next; }如果循环里不小心写成了p p-next后再输出p-data当p已经是NULL时再访问p-data程序就崩了。这类问题新手很难一眼看出来但调试器会精确告诉你崩溃的位置所以学会看调用栈真的很重要。内存泄漏malloc了却不free程序运行久了内存占用会越来越大。在数据结构里最常见的场景就是链表删除节点时忘了free。检查内存泄漏可以用Valgrind工具虽然设置起来有一点学习成本但排查效果确实好得多。面试里也常常会追问删除链表中某个节点除了修指针还应该做什么答案就是free千万别把这个漏了。逻辑边界错误很多程序不是崩溃而是输出错误。这种时候我用一个笨办法设置多个小规模测试用例尤其是空表、单元素表、表头插入、表尾删除这些边界场景逐个跑一遍配合单步调试看每一步变量的值是否符合预期。很多逻辑错误其实就是某个地方少写了等于号、循环条件多了等号、先赋值后移动指针这些细节造成的。初始化错误与野指针很多人声明LinkList L之后不初始化就拿来操作链表就会指向一段未知内存程序崩溃或行为诡异。正确做法是一开始就L NULL所有使用前都判断是否为空。还有结构体内部如果有指针字段使用前也要初始化。我自己写代码时会习惯给所有新定义的指针变量赋初值这个习惯帮我排掉了很多潜在问题。7. 学习路线与资料搭配的实用建议7.1 适合不同基础的资料搭配方案如果你完全零基础我的建议路径是先花一到两周补C语言基础重点覆盖数组、结构体、指针、动态内存分配、函数与递归。推荐翁恺老师的C语言课程作为打基础的部分然后搭配C-Free 5.0或Dev-C作为练习环境。基础补好后再进入严蔚敏版数据结构教材。如果你已经有点C基础直接看严蔚敏版就行但不要只看不练。每个章节结束后到Online Judge上找对应的题目刷一遍比如顺序表、链表、栈、队列、二叉树、图的题目都至少有十道经典题。刷题可以帮你在Debug中真正理解数据结构只是看书的话很容易产生“我懂了”的错觉一旦动手写代码就露馅。我在带学弟学妹时经常说如果你没为一道链表的题调过半小时以上你对链表的理解就还很浅连Debug的过程本身就是最好的学习素材。如果你是为了考研建议再配一本王道的数据结构辅导书重点做历年真题和知识点总结。王道这本书把考纲内的知识点梳理得非常清楚也和严蔚敏版教材互为补充严蔚敏版重在原理和代码实现王道重在应试总结和题目训练。7.2 我可以分享的几个长期有效的学习技巧第一建立一个自己的“算法代码库”。每学完一个数据结构就把它的完整实现在本地工程里整理好包括头文件、实现文件和测试主程序。文件名用英文每个文件头部写好功能说明和关键注意事项。这些东西是你期末复习、考研复习、面试前冲刺的重要素材比任何网盘资料都更符合你的理解习惯。第二尝试不看代码重构实现。学完单链表后合上书开一个空白编辑器从头写一遍单链表的创建、插入、删除、遍历。写完之后再去对照教材把不一样的实现逐行思考原因。这个过程非常痛苦但效果极其显著。我做题时遇到瓶颈时经常用这种“白纸化输出”来定位自己到底哪里没搞懂。第三准备一个错题本。手工模拟的题目比如KMP的next计算、哈希表构造、快排过程模拟出错后把题目和错误步骤粘贴下来在旁边用红字写清楚错因。考前复习只看错题本就够了比从头翻教材高效很多。8. 写在最后的一点经验回头再看数据结构C语言版这门课我最大的感想是它其实不是一门“语言课”也不只是一门“理论课”它是在帮你建立计算思维。在数据结构的学习过程中你练的是如何把一个实际问题抽象成数据结构再把这个数据结构用代码落地并分析它的时间和空间成本。这套思维会渗透到你后续所有的系统设计、项目开发、架构选型里。我在实际带人的过程中发现一个很普遍的现象能把链表、二叉树、排序算法学扎实的人学操作系统、计算机网络、数据库原理时也都相对轻松。因为这些课程本质上都在用数据结构的基本思想。建议大家手边常备一本纸质书用来做笔记和画图电脑开一个编辑器用来跑代码。两者交替进行效率最高。学习过程中遇到不懂的概念优先自己动手画图和调试验证而不是马上去问人。这种独立解决问题的习惯比任何具体的知识点都更重要。希望这篇梳理对你的数据结构学习有帮助。如果哪一章你觉得特别吃力别怕这不是你一个人的问题大家都经历过。静下心来一行一行代码去跑一张一张图去画等你调试通第一个链表程序的那一刻你会觉得前面所有的纠结都值得。