🚀 引言
在 408 考研数据结构中,线性表 与栈 是所有复杂数据结构(如树、图)的基石。今日复习重点在于攻克链表指针引用的底层逻辑 以及栈操作的边界条件。
一、 单链表(Linked List)基础与内存分配
1.1 结构体定义
在代码实现中,必须清晰定义结点结构。
cpp
typedef struct LinkNode {
int data; // 数据域
struct LinkNode *next; // 指针域
} LinkNode;
1.2 动态内存分配
在 C 语言中使用 malloc 申请空间时,务必注意强制类型转换:
- 示例 :
p = (LinkNode *)malloc(sizeof(LinkNode)); - 方法总结 :由于
malloc返回void*类型,在 C++ 环境或严格的 C 编译器中,必须显式转换为LinkNode*才能适配目标指针。
二、 【核心方法】指针引用的"变"与"不变"
这是考研算法题中最容易丢分的地方。关于函数参数中 &L 与 L 的选择,可以总结为以下准则:
2.1 使用 &L(地址传递/引用)
- 核心逻辑 :当函数内部操作会导致 L 的指向发生改变时。
- 适用场景:
- 初始化头结点(L 从 NULL 变为指向具体地址)。
- 头插法/尾插法改变头指针。
- 操作分类:增、删、改。
2.2 使用 L(值传递)
- 核心逻辑 :当函数内部操作时 L 的指向保持不变,仅需访问或修改链表内部结点内容时。
- 适用场景:
- 遍历链表打印数据。
- 按值查找、按序查找。
- 操作分类:查、找、打印。
三、 单链表操作的"核心算法逻辑"
3.1 插入与删除操作
- 插入逻辑(前驱/后继):
- 查找目标位置。
- 创建新结点
s。 - 指针调整(防断链) :
s->next = p->next; p->next = s;
- 删除逻辑:
- 查找待删结点的前驱
p。 - 暂存待删结点
q = p->next。 - 断链重连 :
p->next = q->next; - 释放内存 :
free(q);
3.2 辅助操作
- 单链表置空 :
L->next = NULL; - 自增运算细节:
++k:先执行 +1+1+1,再参与后续判断。k++:先参与当前判断,执行完毕后再 +1+1+1。
四、 栈(Stack)专题:合法性与实现差异
4.1 出栈序列合法性(卡特兰数)
当 nnn 个不同元素依次入栈时,合法的出栈序列个数通过卡特兰数(Catalan)计算:
Cn=1n+1C2nnC_n = \frac{1}{n+1} C_{2n}^{n}Cn=n+11C2nn
4.2 顺序栈的两种实现对比
栈顶指针 top 的初始定义不同,直接影响入栈与出栈的代码实现:
| 栈顶指针指向 | 初始化状态 | 入栈操作 (Push) | 出栈操作 (Pop) |
|---|---|---|---|
| 指向栈顶元素 | top = 0 |
S[++top] = e |
e = S[top--] |
| 指向栈顶上方空位 | top = -1 |
S[top++] = e |
e = S[--top] |
五、 408 考纲重难点分布预测
根据复习心得,数据结构各章节在算法大题中的分值占比大致如下:
- 数组(线性表应用) :50-60%(核心大题高发区)
- 链表 :30%
- 树与图 :20%
考研复习是一场苦修,但脚踏实地走过的每一步,都是你最坚固的护城河。
如果今天的复盘对你有启发,欢迎 一键三连(点赞、收藏、评论) 支持一下!