
很多人翻开《数据结构》第1章第一反应大概率是这页怎么全是概念逻辑结构、存储结构、抽象数据类型、时间复杂度……每个字都认识连在一起就不知道在说什么。尤其是准备期末考试、考研408或者软考的朋友往往直接跳过这一章去背后面的链表和排序算法结果回头做综合题的时候连“顺序存储和链式存储的区别”这种基础题都会卡壳。我最早学数据结构也干过这种事后来被一道“设计一个算法将数组循环左移k位”的题狠狠教育了一顿才明白第1章不是摆设它是整门课的底层规则。这篇东西不打算复述教材而是按我踩过坑之后的理解把这章真正要学的东西、怎么学、怎么考、怎么用到实验报告和代码里一次性讲透。适合三类人看刚开课想打基础的在校生、期末或考研前突击复习的人、工作后想回头补内功的开发者。1. 学数据结构的第1章到底在解决什么问题1.1 这一章不是“概念背诵章”是“规则制定章”很多教材把第1章写成“数据结构基本概念”其实核心就三件事数据怎么组织、数据支持哪些操作、操作的效率怎么评估。这三件事对应到后面每一章线性表是怎么组织数据的栈和队列是加了限制的数据组织方式树和图是更复杂的组织方式排序和查找是操作复杂度分析则是贯穿始终的衡量标准。所以第1章实际上是整门课的“宪法”它规定了后面所有章节讨论问题时的统一语言。比如说后面说“顺序表支持随机访问”如果你不理解“顺序存储结构”意味着数据在内存里是一段连续的单元你就没法真正明白为什么它是O(1)而不是O(n)。这个概念在第1章就出现了但很多人没意识到它有多重要等学到后面才回头补效率就低了。我个人的建议是学第1章的时候不要急着去背定义而是反复问自己一个问题如果我要在程序里存一组数据我有哪几种存法不同存法对增删改查有什么影响把这个问题想清楚了第1章的很多概念就自然串起来了。1.2 数结构在整门课里的位置它是地基中的地基数据结构这门课的知识体系大致可以分三层。最底层就是第1章的基本概念和复杂度分析中间层是各种具体的数据结构从线性表、栈、队列到树、图再到散列表最上层是建立在数据结构之上的算法比如排序、查找、遍历。如果你把第1章当“过场”后面就会遇到一种很奇怪的情况看代码能看懂讲思路也能讲出来但一旦题目换个问法就不知道考什么。原因就是你没有掌握“底层规则”。比如同样是“删除元素”在顺序存储里要移动大量元素在链式存储里只需要改几个指针为什么因为两种存储结构对“逻辑相邻”的实现方式不一样。这个区别在第1章就已经奠定了。从考试角度看考研408、学校期末、软考几乎所有题目最终都在考“结构选型”和“复杂度分析”这两件事。结构选型就是给你一个场景你选什么逻辑结构和存储结构复杂度分析就是给你一段代码你算它的时间开销。这两项能力全部是从第1章长出来的。地基不牢后面盖多少层都虚。2. 四个必须吃透的核心概念逻辑结构、存储结构、ADT、复杂度2.1 逻辑结构数据之间是什么关系逻辑结构描述的是数据元素之间的抽象关系不关心它们在电脑里怎么存。教材上通常分四类集合、线性结构、树形结构、图状结构。集合元素之间“同属于一个集合”除此之外没有其他关系就像一袋子互不相同的珠子。线性结构元素之间是一对一的关系有且仅有一个起点和一个终点每个元素最多有一个直接前驱和一个直接后继。典型的例子就是排队每个人前面最多一个人后面最多一个人。树形结构一对多的关系一个父节点可以有多个子节点比如公司的组织架构、家族谱系。图状结构多对多的关系任意两个节点之间都可能有关联比如地铁线路图、社交网络。理解逻辑结构的关键是把它和“物理上怎么存”分开。同一个逻辑结构可以用不同的物理存储方式来实现。比如一个线性表逻辑上就是一条线性的序列但物理上可以用数组连续存储也可以用链表散落地存储。这是第1章最核心的思维切换也是初学者最容易混的地方。2.2 存储结构数据在内存里到底怎么放存储结构也叫物理结构是逻辑结构在计算机中的实现方式。经典的四种顺序存储、链式存储、索引存储、散列存储。顺序存储好理解就是把数据元素放到一片连续的存储单元里像电影院连排的座位一个挨一个。优点是可以通过下标直接算地址随机访问很快缺点是插入和删除往往要移动元素而且需要预先分配空间扩容麻烦。链式存储是用指针把分散在内存各处的节点串起来每个节点除了存数据还存下一个节点的地址。优点很明显插入删除只要改指针不需要搬动元素缺点是不能随机访问想找第k个节点必须从头一个个走而且每个节点要额外存指针内存开销更大。索引存储是在数据之外建一张索引表每个索引项指向一个数据元素相当于书的目录。查目录能快速定位页码但目录本身也要占空间。散列存储是根据关键字直接计算出存储地址实现“一次定位”也就是哈希表这个后面专门有一章第1章只需要知道它是存储结构的一种。我当年区分顺序和链式靠的是这个类比顺序存储像一群人在一间教室里按学号坐老师喊“学号35号”直接看过去链式存储像一队人玩“传话”每个人只知道下一个人是谁想找队尾必须从头一个一个问过去。这个类比帮我在考试里避开了很多迷惑选项。2.3 抽象数据类型 ADT把“有什么”和“能干什么”打包ADTAbstract Data Type这个概念初看很抽象其实特别接地气。它把数据对象、数据关系、基本操作这三样东西打包成一个整体对外只暴露“能干什么”不暴露“怎么实现”。打个比方你家里的微波炉就是一个ADT。外部面板上有“加热”“解冻”“烧烤”这些按键这是基本操作你不需要知道里面的磁控管怎么工作、电路怎么走线这就是信息隐藏。你用微波炉热饭不需要懂电磁学你用栈的push/pop也不需要每次关心底层是数组还是链表——只要接口一致换实现不影响你用。在写代码的时候ADT思维的价值尤其大。比如你定义一个“学生管理系统”如果一开始就把增删改查的接口定义清楚后面把顺序存储换成链式存储只需要改实现调用方代码不用动。这就是为什么要学第1章它不是让你背“抽象数据类型”五个字而是让你建立“接口和实现分离”的工程意识这在后面的实验和实际项目里会反复用到。2.4 算法复杂度衡量代码好坏的尺子复杂度包括时间复杂度和空间复杂度。时间复杂度不是精确到“运行了多少秒”而是看算法执行时间随数据规模 n 的增长趋势。空间复杂度同理是看额外内存随 n 的增长趋势。判断时间复杂度有一个很实用的小技巧找循环。单层循环一般是O(n)双层嵌套循环一般是O(n²)三分治类的递归一般是O(n log n)。但要注意不是所有循环都乘起来要看循环变量和问题规模n的关系。比如下面这个求和代码int sum 0; for (int i 0; i n; i) { sum i; }这个循环执行n次时间复杂度O(n)。但如果改成用等差数列求和公式int sum n * (n - 1) / 2;时间复杂度直接变成O(1)。第1章的复杂度题核心就是让你掌握这种“从循环次数推导增长率”的能力后面排序算法、树和图的操作全部建立在它之上。3. 把第1章变成能跑的代码实验报告与上机实操3.1 第一个实验该写什么别一上来就写二叉树很多学校的实验课一上来就是“实现顺序表”“实现单链表”听着挺简单但对完全不懂C语言指针的人来说写出来的代码全是bug。我的建议是第1章阶段先做三个小实验难度递进正好覆盖本章概念用数组实现一个整数集合的并集运算练逻辑结构里的集合概念。用结构体和指针实现单链表的创建与遍历练链式存储。用数组模拟一个循环队列实现入队出队练线性结构和对“队头队尾指针”的理解。这三个实验不需要多大代码量但能逼你把第1章的概念落到语法上。特别是第二个涉及结构体、指针、动态内存分配这些是后面一切数据结构的操作基础。我自己带过几次课程设计发现一个规律凡是链表部分靠抄的同学后面学到树时一定崩溃。因为树的节点定义、遍历逻辑和链表是同构的只是多了一两个指针域。第1章把链表写熟了后面是复利式收益。3.2 单链表实验的C语言骨架照着敲就能跑下面给一个最基础的单链表创建和遍历的代码骨架注释写得比较细#include stdio.h #include stdlib.h typedef struct Node { int data; // 数据域 struct Node *next; // 指针域指向下一个节点 } Node; // 尾插法创建链表n 是节点个数 Node *createList(int n) { Node *head NULL; // 头指针 Node *tail NULL; // 尾指针方便尾插 for (int i 1; i n; i) { Node *p (Node*)malloc(sizeof(Node)); if (p NULL) { printf(内存分配失败\n); return head; } p-data i * 10; // 给节点赋值 p-next NULL; if (head NULL) { head p; // 第一个节点既是头也是尾 } else { tail-next p; // 原尾节点指向新节点 } tail p; // 更新尾指针 } return head; } // 遍历链表 void printList(Node *head) { Node *p head; while (p ! NULL) { printf(%d , p-data); p p-next; // 移到下一个节点 } printf(\n); }这段代码的要点就三个malloc申请节点、tail-next串接新节点、p p-next移动遍历。如果你能自己独立把这几个动作写出来第1章关于链式存储的学习就过关了大半。顺便说一句malloc之后一定要判断返回是否为空这是很多同学实验报告里被扣分的地方也是实际编程中防止程序崩溃的底线习惯。3.3 实验报告该怎么写才不会被老师一眼看出是抄的写实验报告是门手艺活。我发现很多同学的实验报告开头全是教材原文代码部分是网上复制的一大坨结果分析和测试数据只写一句话。这种报告其实很吃亏因为老师看几千份实验报告真正判断你是不是理解了全靠“问题分析”和“结果分析”这两块。以链表实验为例一份及格的实验报告至少要包括这么几块问题描述实验要求做什么不要抄题干用自己的话说。设计思路数据结构为什么用单链表不用顺序表这是最体现理解力的地方。你可以写“预计插入删除操作较多链式存储不需要移动元素”。核心代码不必须全贴但要贴关键函数并在旁边加注释说明每个参数和步骤的作用。测试结果给出一组输入和对应输出最好包含边界情况比如空链表遍历、删除第一个节点。复杂度分析创建链表O(n)、遍历O(n)、在第i个位置插入O(n)因为要先找到前驱每个结论都要写出理由。我特别想强调复杂度分析这一栏。它看起来像个形式但它是把第1章概念和代码连接起来的桥梁。你写了复杂度分析才算真正用上了第1章的知识。不写你就是在做“打字练习”而不是数据结构实验。4. 期末、考研、软考、408视角下的第1章考点4.1 这三个场景的考法差异很大别用同一种方式复习数据结构的考试场景五花八门学校期末、考研408、软考中级/高级虽然都考数据结构但出题风格完全不同。学校期末的特点是概念题多判断题、选择题、填空题占了半张卷子比如“线性结构只能采用顺序存储这句话对吗”答案是错的这类题专治“只背结论不理解原理”的人。只要你把逻辑结构和存储结构的对应关系想明白这些题就是送分。考研408的风格是“计算量大代码风格强”。第1章最常考的是复杂度分析而且经常出往年真题里的老题比如“求下列代码的时间复杂度for(i1; in; i*2)”这种答案是O(log n)。408还会考察ADT描述、逻辑结构与存储结构的匹配偶尔在算法设计题里让你自己定义结构体完全就是在检验你是不是真的懂底层实现。软考的风格更偏工程应用喜欢考“在某个场景下用哪种存储结构最优”比如“一个频繁在表头插入删除的线性表用哪种存储方式最好”答案是链式存储。软考还喜欢把数据结构和数据库、操作系统结合着考反正底层逻辑都是第1章这套东西。不管你考哪种第1章的复习主线都是概念题靠理解刷题复杂度题靠熟能生巧代码题靠上机练习。只想考前背几页PPT是绝对不够的。4.2 高频易错点这些坑我几乎每一届都见到学生踩先说第一坑把“逻辑结构”和“存储结构”混为一谈。题目说“树是逻辑结构二叉树是树的一种”有同学就会问“那二叉树到底存的连续还是链式”这就是混淆了。逻辑结构描述关系存储结构描述实现同一棵二叉树既可以用数组存顺序存储也可以用孩子兄弟链表存链式存储两者不冲突。考试里一看到“逻辑”两个字就往关系上想一看到“存储”两个字就往内存布局上想。第二坑复杂度只算循环次数不看数据规模变化。比如代码里循环条件是i n但循环里i i 2那么执行次数是n/2还是O(n)。很多同学不会区分常数系数和增长率。记住O()表示法丢掉常数和低阶项但不要丢掉n的数量级。第三坑malloc和free不配对。写实验的时候创建链表用了malloc程序结束前没free虽然考试不扣分但如果你以后做项目内存泄漏会把你折磨到崩溃。我面试候选人的时候经常问“free之后指针要不要置NULL”能答上来的不多这就是基础没打牢的表现。第四坑头节点理解不到位。很多教材在链表里加了“头节点”它不存数据只用来统一插入删除的逻辑。有同学理解不了为什么要有头节点考试做题就在头指针和头节点上绕晕。你用个例子辅助理解带头节点时删除第一个元素和删除其他元素的代码可以写成一样的不带头节点删除第一个元素要单独处理。这就是引入头节点最大的好处。4.3 一张顺序复习清单照着执行就行结合这些年的经验我整理了一个第1章的复习清单不管你是期末、考研还是软考按这个顺序走基本不会出问题先花两小时通读教材第1章重点标出四类概念逻辑结构、存储结构、ADT、复杂度。画一张自己的结构图左边写逻辑结构的四类右边写存储结构的四种中间用箭头连线标注“可以组合”。这张图能成为你的“概念地图”。刷20道小题判断题和选择题都行专门检验你对概念边界的理解比如“链式存储只能用于线性结构吗”错树和图也可以用链式存储。动手跑代码实现一个有头节点的单链表至少完成创建、遍历、在第k个位置插入、删除第k个节点四个操作。每个操作都做一次复杂度分析。整理易错点本子把错的题和原因都写下来考前只看这个本子就行。这套流程看着简单但每一步都在练第1章的真实能力概念辨析、复杂度推导、代码操作。比我当年闷头背书强太多。5. 教材和资源怎么选严蔚敏、王道、李春葆、赵海英怎么用5.1 主流参考书各有脾气别迷信任何一本C语言版的严蔚敏《数据结构》是经典中的经典几乎所有学校的课件都参考它。但这本书对新手非常不友好很多代码的实现思路偏学术逻辑严谨但阅读门槛高尤其是第二章的线性表部分光一个“线性表的链式存储”就能劝退不少人。我的看法是严蔚敏适合当“字典”用遇到术语不清晰的时候去查不适合从头啃。王道考研系列是很多考研党的救命书它的特点是考点密集、题型全、总结到位尤其是选择题的解析写得很详细。但它对应的主要是考试对工作实践帮助有限。如果目标是考研408王道加真题就够如果你想在实验里学到真正的工程能力还得配合上机练习。李春葆的《数据结构习题与解析》是题库型的题目量大、分类清楚适合期末和考研刷题。它的答案详细能帮你纠正很多思路偏差。语言相对啰嗦不适合快速过知识点。赵海英的数据结构课程在网上的资源比较多有人求过她的百度云资料和PDF课件。她的视频风格偏学院派讲得系统全面适合你自学时跟着走。但我必须提醒一点网上流传的电子书和视频资源很多版本老旧、画质模糊甚至和你的教材版本对不上使用时要留意核对知识点顺序。5.2 电子书和视频资源怎么搭配高效又不踩坑资源太多反而是灾难。我的实际体验是认准“一本教材 一套网课 一个题库”的配置不要贪多。教材选严蔚敏或学校指定版本用来查概念和看代码。网课选一个你能听下去的老师B站上搜数据结构选播放量高、评论区口碑好的。赵海英、王道咸鱼老师的都行关键是连续跟完一遍别换。题库选王道或李春葆按章节刷题错题标记到本子上。网上常见的“数据结构c语言版严蔚敏电子书pdf”“数据结构严蔚敏第三版pdf”这类资源我建议下载归下载PDF只适合零散查阅系统性学习还是买实体书。原因很简单数据结构的代码在屏幕上看效率很低纸质书方便在书上标注画图。尤其是第1章的复杂度推导需要反复勾画电子书翻页翻到崩溃。5.3 关于“数据结构八股文”和“代码必背”我的态度是别背不会的现在网上流传“数据结构八股文”和“408数据结构代码必背”里面确实总结了不少高频考点比如链表逆置、二叉树遍历的非递归写法、快排的partition模板。这些总结有一定价值能用它快速回忆知识点但我不建议你拿着它死记硬背。原因是数据结构考的是“理解之下的复现”不是“记忆之下的默写”。你背下来一个链表逆置代码考试题目稍微改成“将链表每k个节点逆置一次”你就抓瞎了。真正靠谱的做法是把高频代码的每一行吃透知道为什么要设三个指针、为什么要先保存next再改指针。吃透一个模板比死背十个模板管用得多。所以我建议把“八股文”和“代码必背”当作最后的复习提纲考前一周用来查漏而不是当作唯一学习材料。6. 我踩过的一些坑和几条保命经验6.1 “听懂了但不会做题”的真相很多同学听第1章的课觉得老师讲的都懂逻辑结构、存储结构、ADT不抽象啊。但一做题就懵什么排序算法比较次数、什么“在顺序表中插入元素的平均移动次数”完全不知道从哪下手。这个问题的根源是听懂了课堂上的例子但没把概念迁移到新场景。听懂了“排队是线性结构”不等于你会分析“字符串也是线性结构”听懂了“顺序表插入要移动元素”不等于你会推导“平均移动n/2次”。迁移能力只能靠做题练没有捷径。我做题的方法比较土每道题不管对错都强迫自己写出“这道题考察了第1章哪个概念”。写不出来说明这道题我没真正理解。这个方法帮我从“听懂了”变成“会做了”。6.2 学习节奏安排好第1章别拖也别赶第1章内容不多但概念密度高。我见过两种极端一种是一周连翻30页看完全忘一种是卡在“大O表示法”上整整半个月进度停滞。比较合理的时间安排是三天到一周。第一天过概念把逻辑结构、存储结构、ADT理解清楚第二天专门搞复杂度把例题手算一遍再自己出几道题验证第三天到第五天上机写代码把链表实验做完剩下的时间刷题和整理错题。战线太长容易疲劳太短则消化不良。我自己最喜欢的时间节奏是“每天专注2小时连续5天”比周末疯狂学一整天效果好得多因为每天接触的时间短大脑有时间做“后台固化”第二天再看昨天的内容会觉得很简单。6.3 最后分享一个压箱底的小技巧把每章压缩到一张A4纸从第1章开始我会在学完一个大的知识块后把核心知识点压缩到一张A4纸上。不用写很长就写关键术语、关键公式、典型例、易错点。比如第1章的A4纸上我会写逻辑结构集合、线性、树、图一对一、一对多、多对多存储结构顺序、链式、索引、散列连续vs分散、随机vs顺序ADT数据对象 关系 操作接口与实现分离复杂度找循环、算次数、去掉常数和低阶项易错顺序存储不一定是数组链式存储不是只能存线性结构这张纸在身边的好处是每天花一分钟扫一眼知识点不容易忘。到了期末或者考前这本“A4纸集”就是你最有力的复习资料。我靠这个方法期末复习时间压缩了至少三分之一而且心里特别有底。