#数据结构----2.1线性表

在数据结构的学习中,线性表是最基础、最核心的结构之一 ------ 它是后续栈、队列、链表等复杂结构的 "基石"。今天从 "是什么"(定义)到 "怎么用"(基本操作),彻底搞懂线性表的核心逻辑。

一、先明确:数据结构的三要素

在聊线性表之前,必须先记住数据结构的核心三要素,这是理解所有结构的前提:

逻辑结构:数据元素之间的 "关系"(比如线性表的 "前后顺序");

数据的运算:对数据元素能做的操作(比如增、删、改、查);

存储结构(物理结构):数据在内存中的 "存放方式"(比如数组、链表)。

关键提醒:存储结构不同,运算的实现方式也不同(比如数组实现和链表实现的 "插入" 操作,底层逻辑完全不一样),但今天我们先聚焦 "逻辑结构" 和 "运算"。

二、线性表的定义:到底什么是线性表?

线性表是具有相同数据类型的 n(n≥0)个数据元素的有限序列,用 L 命名时可表示为:

( L = (a_1, a_2, ..., a_i, a_{i+1}, ..., a_n) )

我们拆解这个定义里的关键信息,再结合例子理解会更透彻:

1. 定义的 3 个核心特性

  • 同类型:所有元素的数据类型必须一致(比如全是整数、全是学生信息);

  • 有限性:元素个数 n 是有限的(不存在无限个元素的线性表);

  • 有序性:元素之间有明确的 "前后顺序"(a₁ 在 a₂ 前面,a₂ 在 a₃ 前面,不能乱序)。

2. 几个必须分清的术语

术语 含义
表长 线性表中元素的个数 n(n=0 时为空表)
表头元素 第一个元素 a₁
表尾元素 最后一个元素 aₙ
直接前驱 除 a₁ 外,每个元素 aᵢ 前面的那个元素(即 aᵢ₋₁)
直接后继 除 aₙ 外,每个元素 aᵢ 后面的那个元素(即 aᵢ₊₁)
位序 元素在表中的 "位置编号"(从 1 开始!和数组下标从 0 开始形成区别)

3. 举个例子:哪些是线性表?

  • 例 1:所有整数按递增顺序排列(1,2,3,4,...100)------ 同类型(整数)、有限(100 个)、有序(递增),是线性表;

  • 例 2:学生信息表(如下表)------ 同类型(学生信息)、有限(10 条记录)、有序(按学号排序),是线性表;

学号 姓名 专业
1120112100 张三 挖掘机
1120112101 李四 挖掘机
1120112102 王玉玉 数据挖掘
  • 例 3:学习计划列表(学习《C 语言》→ 学习《数据结构》→ 学习《架构师》)------ 同类型(学习任务)、有限、有序,也是线性表。

三、线性表的基本操作:从 "创" 到 "销" 全流程

为什么要定义基本操作?核心原因有两个:

  1. 团队协作:封装好的操作能让其他人直接用,不用重复理解底层逻辑;

  2. 减少错误:常用操作写成函数,避免重复编码导致的 bug。

线性表的操作可以按 "生命周期" 和 "功能" 分为 4 类,我们逐个拆解(重点关注 "是否需要传引用 &"):

1. 创销类:线性表的 "出生" 与 "消亡"

这两类操作是线性表的基础 ------ 从 "无" 到 "有",再从 "有" 到 "无"。

  • InitList (&L):初始化表

功能:构造一个空的线性表 L,并为其分配内存空间。

为什么传 &L?因为要修改 L 本身(给它分配内存、设置表长为 0),需要把修改结果 "带回来"。

  • DestroyList (&L):销毁表

功能:销毁线性表 L,并释放它占用的内存空间(避免内存泄漏)。

为什么传 &L?因为要释放 L 指向的内存,修改 L 的状态(比如让 L 指向 NULL),需要带回报错结果。

2. 增删类:改变线性表的 "长度"

这两类操作会修改线性表的元素个数,是高频操作。

  • ListInsert (&L, i, e):插入元素

功能:在表 L 的第 i 个位置,插入新元素 e(插入后表长 +1)。

传参说明:&L(要修改表的结构)、i(插入位置,需满足 1≤i≤表长 + 1)、e(要插入的元素)。

  • ListDelete (&L, i, &e):删除元素

功能:删除表 L 第 i 个位置的元素,并用 e 保存被删除元素的值(删除后表长 -1)。

为什么 &e?因为要把 "被删除的元素值" 带回来(比如用户需要知道删了什么)。

3. 改查类:定位元素("改" 的前提是 "查")

"查" 是 "改" 的基础 ------ 要修改元素,必须先找到它的位置或值。

  • GetElem (L, i):按位查找

功能:获取表 L 第 i 个位置的元素值(i 需满足 1≤i≤表长)。

为什么不传 &L?因为只是 "读取" 元素,没有修改表的结构或内容,不需要带回结果。

  • LocateElem (L, e):按值查找

功能:在表 L 中查找 "值等于 e" 的元素,返回它的位序(若找不到返回 0 或 NULL)。

同理,仅读取,不传 &L。

4. 其他常用操作:辅助功能

这些操作是对线性表的 "补充查询",高频且实用:

  • Length (L):求表长:返回表 L 中元素的个数 n;

  • PrintList (L):输出表:按前后顺序打印所有元素(比如打印学生信息表);

  • Empty (L):判空:若表 L 为空(n=0)返回 true,否则返回 false。

关键考点:什么时候传引用 "&"?

当对参数的修改结果需要 "带回来" 时,必须传引用(或指针)

比如:

  • 不传 & 的情况:调用 test(x) 后,x 的值在主函数中不变(修改只在 test 内部生效);

    c 复制代码
    #include<stdio.h>
    void test(int x){
    	x=1024;
    	printf("test函数内部 x=%d\n",x);
    }
    int main(){
    	int x=1;
    	printf("调用test前 x=%d\n",x);
    	test(x);
    	printf("调用test后x=%d\n",x);
    }
  • 传 & 的情况:调用 test(&x) 后,x 的值在主函数中会被修改(修改结果带回来了)。

    c++ 复制代码
    #include<stdio.h>
    void test(int & x){
        x=1024;
        printf("test函数内部 x=%d\n",x);
    }
    int main(){
        int x=1;
        printf("调用test前 x=%d\n",x);
        test(x);
        printf("调用test后x=%d\n",x);
    }

对应到线性表操作:

需要传 &L 的操作:InitList、DestroyList、ListInsert、ListDelete(都修改了 L 的结构或内容);

不需要传 &L 的操作:GetElem、LocateElem、Length、PrintList、Empty(仅读取,不修改)。

四、总结:线性表的核心要点

逻辑结构核心:同类型、有限、有序,每个元素(除首尾)有唯一前驱和后继;

操作记忆思路:按 "创销→增删→改查" 的生命周期记忆,辅助 "判空、表长、打印";

传参关键:修改需 "带回结果" 则传 &,仅读取则不传;

注意细节:位序从 1 开始(和数组下标区分),函数命名要可读(比如 InitList 比 fun1 更易理解)。

复制代码
相关推荐
XiaoFan0127 分钟前
将有向工作流图转为结构树的实现
java·数据结构·决策树
睡一觉就好了。19 分钟前
快速排序——霍尔排序,前后指针排序,非递归排序
数据结构·算法·排序算法
齐落山大勇24 分钟前
数据结构——单链表
数据结构
皮皮哎哟1 小时前
深入浅出双向链表与Linux内核链表 附数组链表核心区别解析
c语言·数据结构·内核链表·双向链表·循环链表·数组和链表的区别
wWYy.2 小时前
指针与引用区别
数据结构
历程里程碑2 小时前
Linux 17 程序地址空间
linux·运维·服务器·开发语言·数据结构·笔记·排序算法
-dzk-3 小时前
【代码随想录】LC 203.移除链表元素
c语言·数据结构·c++·算法·链表
齐落山大勇3 小时前
数据结构——栈与队列
数据结构
毅炼3 小时前
hot100打卡——day17
java·数据结构·算法·leetcode·深度优先
404未精通的狗3 小时前
(数据结构)二叉树(上)
数据结构