【软考中级 - 软件设计师 - 基础知识】数据结构之线性表
线性表是数据结构的 “入门基础”,也是考试高频考点(选择题占比约 5%)。简单说,线性表就是 “数据排成一条直线,每个元素最多只有一个前继和一个后继”—— 比如购物车的商品列表、通讯录的联系人顺序,都属于线性表。考试重点围绕 “两种存储方式(顺序存储、链式存储)” 展开,核心是 “对比差异 + 选对场景”,下文用 “表格对比 + 例子拆解” 讲解。
一、先搞懂:线性表的基本概念
不用记复杂定义,记住 3 个核心特征即可:
- 元素 “一对一”:除了第一个元素(无前继)和最后一个元素(无后继),其他元素都有且只有一个前继、一个后继;
- 元素类型相同:比如线性表存 “整数” 就全是整数,存 “用户对象” 就全是用户对象;
- 长度可变:能添加、删除元素(比如购物车加商品、删商品)。
考试常考的线性表实例:数组、链表、栈、队列(栈和队列是 “特殊的线性表”,后续文章讲)。
二、核心考点 1:线性表的两种存储方式(必背对比)
线性表有两种核心存储方式:顺序存储(对应数组) 和 链式存储(对应链表)。考试 90% 的线性表题目,都是考这两种方式的 “存储特点、操作差异、场景选择”,必须熟记对比表:
对比维度 | 顺序存储(数组) | 链式存储(链表) |
存储结构 | 元素存在连续的内存空间里 | 元素存在不连续内存,靠 “指针” 连起来 |
访问元素 | 按 “下标” 直接访问(比如 arr [2]) | 必须从 “头节点” 开始,依次遍历找元素 |
插入 / 删除元素 | 要移动其他元素(比如中间插元素) | 只需改指针,不用移动元素 |
内存利用率 | 可能浪费(比如数组定长,用不完) | 按需分配,不浪费 |
实现复杂度 | 简单(直接用数组) | 复杂(要管理指针) |
适用场景 | 频繁访问元素,少插入删除 | 频繁插入删除,少访问元素 |
通俗例子理解:
- 顺序存储(数组):像电影院座位,编号 1-100,想找 5 排 3 号,直接按编号走(下标访问);但如果中间有人离开,后面的人要往前挪(插入删除移动元素)。
- 链式存储(链表):像小朋友手拉手排队,想找第 5 个小朋友,必须从第一个开始,一个个问 “下一个是谁”(遍历);但如果中间有人加入 / 离开,只需重新拉手(改指针),其他人不用动。
三、考点拆解 1:顺序存储(数组)的核心操作
顺序存储用数组实现,考试重点考 “插入” 和 “删除” 操作(因为这两个操作涉及元素移动,容易出计算题目)。需掌握 “操作步骤” 和 “移动元素次数计算”。
1. 插入操作:在第 i 个位置插元素(从 1 开始计数)
步骤(以数组 arr [5] = [1,3,5,7,9] 为例,在第 3 个位置插 2):
Step1:判断插入位置是否合法(i 不能小于 1,也不能大于数组长度 + 1);
Step2:从 “最后一个元素” 开始,到 “第 i 个元素”,依次往后移 1 位(避免覆盖);
Step3:把要插入的元素放到第 i 个位置;
Step4:数组长度 + 1。
例子实操:
原数组:[1,3,5,7,9](长度 5),插 2 到第 3 位:
- Step2:移动元素:9→第 6 位,7→第 5 位,5→第 4 位(移动 3 次);
- Step3:第 3 位放 2,数组变成 [1,3,2,5,7,9](长度 6)。
关键计算:插入位置 i,需要移动的元素次数 = 数组长度 - i + 1(比如上例:5-3+1=3 次)。
2. 删除操作:删除第 i 个位置的元素
步骤(以上面插入后的数组 [1,3,2,5,7,9] 为例,删除第 3 个元素 2):
Step1:判断删除位置是否合法(i 不能小于 1,也不能大于数组长度);
Step2:从 “第 i+1 个元素” 开始,到 “最后一个元素”,依次往前移 1 位(覆盖要删除的元素);
Step3:数组长度 - 1。
例子实操:
原数组:[1,3,2,5,7,9](长度 6),删第 3 位:
- Step2:移动元素:5→第 3 位,7→第 4 位,9→第 5 位(移动 3 次);
- Step3:数组变成 [1,3,5,7,9](长度 5)。
关键计算:删除位置 i,需要移动的元素次数 = 数组长度 - i(比如上例:6-3=3 次)。
3. 易错提醒:
- 数组下标从 0 开始还是 1 开始?考试中若没说明,按 “题目描述” 来(比如 “第 i 个位置” 通常从 1 开始,“下标 i” 从 0 开始);
- 插入时若数组已满,需要 “扩容”(考试一般不考扩容细节,只需知道要扩容)。
四、考点拆解 2:链式存储(链表)的核心操作
链式存储用链表实现,每个元素(节点)包含 “数据域”(存数据)和 “指针域”(存下一个节点的地址)。考试重点考 “单链表”(最简单的链表,只有一个指针指向后继)的 “插入”“删除” 和 “遍历”。
1. 单链表的结构(先看懂图)
单链表像 “串珠子”,每个珠子(节点)有两个部分:
- 数据域:比如存整数 1、3、5;
- 指针域:存下一个珠子的地址(比如节点 1 的指针指向节点 3,节点 3 的指针指向节点 5,最后一个节点的指针为 “null”,表示结束)。
记一个简单表示:节点 = (数据, 下一个节点地址),比如单链表:(1, &3) → (3, &5) → (5, null)。
2. 插入操作:在节点 p 后面插新节点 s(考试常考这种场景)
步骤(以上面的单链表为例,在节点 3 后面插节点 2):
Step1:新节点 s 的指针域,指向 p 的下一个节点(即 s→next = p→next,让 s 连向 5);
Step2:p 的指针域,指向新节点 s(即 p→next = s,让 3 连向 s);
(注意:先连 s 的指针,再改 p 的指针,避免丢失 p 原来的后继节点)。
例子实操:
原链表:1→3→5→null;
- Step1:s→next = 3→next(即 s→next 指向 5);
- Step2:3→next = s(即 3 指向 s);
- 结果:1→3→2→5→null。
3. 删除操作:删除节点 p 的后继节点 s
步骤(以上面插入后的链表为例,删除节点 3 后面的节点 2):
Step1:找到要删除的节点 s(即 p 的后继,s = p→next);
Step2:p 的指针域,指向 s 的下一个节点(即 p→next = s→next,让 3 直接连向 5);
Step3:释放 s 的内存(考试一般不考释放细节,知道要释放即可)。
例子实操:
原链表:1→3→2→5→null;
- Step1:s = 3→next(s 是节点 2);
- Step2:3→next = 2→next(3 指向 5);
- 结果:1→3→5→null。
4. 遍历操作:从表头到表尾,访问所有元素
步骤:
Step1:定义一个临时指针,指向表头(比如 temp = 表头);
Step2:如果 temp 不为 null,访问 temp 的数据域,然后 temp = temp→next(移到下一个节点);
Step3:重复 Step2,直到 temp 为 null。
关键:遍历必须从表头开始,不能跳着访问(和数组的下标访问不同),时间复杂度是 O (n)(n 是链表长度)。
五、考点拆解 3:两种存储方式的场景选择(真题高频)
考试常问 “某场景该用数组还是链表”,核心是根据 “操作频率” 选:
场景描述 | 推荐存储方式 | 理由 |
实现 “学生成绩查询系统”(频繁按学号查成绩) | 顺序存储(数组) | 按学号(下标)直接访问,速度快 |
实现 “购物车”(频繁添加 / 删除商品,少批量查询) | 链式存储(链表) | 插入删除不用移动元素,效率高 |
实现 “排行榜”(固定长度,频繁查前 10 名) | 顺序存储(数组) | 查前 10 名直接按下标取,方便 |
实现 “消息队列”(频繁从队头删、队尾加) | 链式存储(链表) | 头尾操作不用移动元素(后续队列会细讲) |
六、备考小贴士(3 步搞定)
- 记对比表:把 “顺序存储 vs 链式存储” 的对比表背下来,尤其是 “访问方式” 和 “插入删除差异”;
- 练操作题:各练 3 道插入 / 删除题(数组练移动次数计算,链表练指针修改步骤),比如 “数组长度 5,在第 2 位插入元素,移动几次?”(答案:5-2+1=4 次);
- 场景对应:看到题目描述 “频繁访问” 选数组,“频繁插删” 选链表,不用想复杂。
下一篇【基础知识】专栏将讲解 “特殊的线性表”—— 栈和队列,它们是线性表的变形,操作有特殊规则(比如栈 “先进后出”),考试中比普通线性表更常考,建议提前回顾本次的线性表存储知识。