首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >轻松理解数据结构:从生活场景看懂顺序表

轻松理解数据结构:从生活场景看懂顺序表

作者头像
fashion
发布2025-12-31 17:50:51
发布2025-12-31 17:50:51
110
举报

在编程学习中,“数据结构” 常常被初学者视为 “拦路虎”,尤其是听到 “顺序表”“链表” 这类专业术语时,很容易陷入 “抽象难懂” 的误区。但其实数据结构的本质,就是为了更高效地管理和操作数据 —— 就像我们日常生活中整理物品的方式一样。今天我们就从最基础的 “顺序表” 开始,用生活化的例子 + 简单代码,把抽象概念变成你能摸得着的 “实用工具”。

一、先搞懂:顺序表到底是什么?像我们生活中的什么?

其实顺序表一点都不复杂,你可以把它理解成 “一个有规则的抽屉柜”—— 每个抽屉大小一样,按顺序排列,里面只能放同一种类型的东西(比如全放书本,或者全放文具),而且你能通过抽屉的 “位置编号” 快速找到对应的物品。

1. 顺序表和数组的关系:“包装好的数组”

如果你学过 C 语言或其他编程语言,一定对 “数组” 不陌生。比如int arr[10]就是一个能存 10 个整数的数组,每个元素有固定的下标(从 0 开始),我们可以通过arr[0]“精准定位” 第一个元素。

顺序表,其实就是在数组的基础上,增加了 “长度管理” 的功能。打个比方:数组就像一个 “没有标签的空抽屉柜”,你知道它有 10 个抽屉,但不知道里面装了多少东西、有没有空抽屉;而顺序表就像给这个抽屉柜贴了一张 “清单”,上面写着 “当前装了 3 件物品”,这样你就不会往已经装满的抽屉里硬塞东西,也不会找不到空抽屉的位置。

用代码来表示的话,顺序表的核心结构是这样的(对应你提供的代码片段):

// 定义顺序表的结构

typedef struct{

elemtype data[maxsize]; // 底层就是一个数组,用来存数据(相当于抽屉柜)

int length; // 记录当前有多少个元素(相当于清单上的“已装数量”)

}seqlist;

这里的elemtype是 “元素类型” 的缩写(代码里用typedef把int重命名为elemtype),意思是这个顺序表可以存整数;maxsize是数组的最大容量(比如 100),代表抽屉柜的 “总抽屉数”;length则是当前实际存了多少个元素,比如你存了 3 个数字,length就是 3。

二、为什么需要顺序表?数组不够用吗?

可能有人会问:既然顺序表底层是数组,那直接用数组不就行了?其实顺序表的价值,就在于解决了数组的 “痛点”——

比如你用数组存数据时,想知道 “现在装了多少个元素”,只能自己遍历数组统计(如果有未赋值的元素,还会统计错);想在指定位置插入一个元素,得自己手动把后面的元素 “往后挪”,还得担心数组会不会越界。

而顺序表把这些 “麻烦事” 都封装成了现成的功能(比如初始化、插入、删除、查找),就像给你提供了一套 “抽屉柜操作指南”,你不用再自己琢磨 “怎么挪抽屉”“怎么记数量”,直接用就行。

三、手把手学顺序表:5 个核心操作,用代码看懂

我们结合你提供的 C 语言代码,一步步拆解顺序表的核心操作 —— 就像教你怎么 “用抽屉柜存东西、取东西、挪东西”。

1. 第一步:初始化顺序表 —— 给抽屉柜 “贴空清单”

初始化的目的,是让顺序表从 “未使用状态” 变成 “可以使用的空状态”。就像你刚买了一个新抽屉柜,第一步要做的不是直接放东西,而是先在清单上写 “当前已装数量:0”,告诉自己 “现在所有抽屉都是空的”。

对应代码:

// 初始化顺序表:把length设为0,代表当前没有元素

void initdata(seqlist *L){

L->length=0; // L是指向顺序表的指针,通过“->”修改length的值

}

使用的时候,你需要先 “创建一个抽屉柜”(定义顺序表变量),再 “贴清单”(调用初始化函数):

seqlist list; // 定义一个顺序表变量(相当于买了一个抽屉柜)

initdata (&list); // 初始化:把list的length设为0(贴空清单)

2. 第二步:在末尾添加元素 —— 往最后一个空抽屉放东西

往顺序表末尾加元素,是最常用的操作之一,就像你往抽屉柜的 “最后一个空抽屉” 里放东西 —— 先看一下清单,知道当前装了 3 件(length=3),就把新东西放进第 4 个抽屉(数组下标是 3,因为数组从 0 开始),然后把清单上的 “已装数量” 改成 4。

对应代码:

// 在顺序表尾端添加元素e(e就是要放的“东西”)

int addseqlist(seqlist*L,elemtype e){

// 先判断:抽屉柜是不是满了?(length >= 最大容量maxsize)

if((L->length)>=maxsize){

printf("顺序表已满");

return 0; // 满了就返回0,代表添加失败

}

// 没满的话,把e放进“最后一个空位置”(下标=length)

L->data[L->length]=e;

L->length++; // 清单数量+1

return 1; // 返回1,代表添加成功

}

比如代码里添加了 4 个数字:8、88、888、8848,就像往抽屉柜里依次放了 4 件东西,此时length变成 4,数组里的数据就是[8,88,888,8848]。

3. 第三步:在指定位置插入元素 —— 把东西插进两个抽屉中间

生活中我们常会遇到 “中间插东西” 的场景:比如抽屉柜里已经放了 4 本书(位置 1 到 4),现在想把一本新书插进 “位置 2”,就需要先把位置 2、3、4 的书往后挪一个抽屉,腾出位置再放新书。顺序表的插入操作也是一样的逻辑。

对应代码:

// 在pos位置插入元素e(pos是用户输入的“要插的位置”)

int insertlist(seqlist*L,int pos,elemtype e){

// 先判断:插入的位置是不是合理(比如不能比当前元素数量还大)

if(pos<L->length){

// 把pos位置及后面的元素“往后挪一位”(从最后一个元素开始挪,避免覆盖)

for(int i=L->length;i>=pos;i--){

L->data[i+1]=L->data[i];

}

// 腾出位置后,把e放进pos-1的下标(因为数组从0开始,位置1对应下标0)

L->data[pos-1]=e;

L->length++; // 数量+1

}

}

比如你想在 “位置 2” 插入数字 10,原来的数组是[8,88,888,8848],执行插入后会变成[8,10,88,888,8848]—— 就像把第 2 个抽屉的书往后挪,再把新书放进去。

4. 第四步:删除指定位置元素 —— 把抽屉里的东西拿走,后面的往前挪

删除操作和插入操作是 “反过来” 的:比如你想把抽屉柜 “位置 3” 的东西拿走,就需要先把位置 3 的东西取出来,再把位置 4、5 的东西往前挪一个抽屉,填补空出来的位置,最后把清单上的 “已装数量” 减 1。

对应代码:

// 删除del位置的元素,并用e指针返回被删除的元素(方便用户查看删了什么)

int deleteelem(seqlist*L,int del,elemtype *e){

// 先把要删除的元素存起来(比如要删位置3的元素,就先把data[2]存到*e里)

*e=L->data[del-1];

// 判断删除位置是否合理

if(del<L->length){

// 把del位置后面的元素“往前挪一位”(从del位置开始挪)

for(int i=del;i< L->length;i++){

L->data[i-1]=L->data[i];

}

}

L->length--; // 数量-1

return 1; // 删除成功

}

比如你删除 “位置 2” 的元素,数组[8,10,88,888,8848]会变成[8,88,888,8848],同时会返回被删除的元素 10—— 就像把第 2 个抽屉的东西拿走,后面的书往前补位。

5. 第五步:查找元素 —— 根据 “东西” 找它在哪个抽屉

查找操作就像 “找东西”:比如你想找抽屉柜里有没有 “88” 这本书,就从第一个抽屉开始逐个翻看,直到找到对应的抽屉位置;如果没找到,就告诉自己 “没有这本书”。

对应代码:

// 查找元素e,返回它的位置(从1开始数,方便用户理解)

int findelem(seqlist*L,elemtype e){

// 遍历顺序表,逐个对比元素

for(int i=0;i<L->length;i++){

if(L->data[i]==e){

return i+1; // 找到就返回位置(下标i+1,因为用户习惯从1开始数)

}

}

}

比如你查找 “88”,代码会遍历数组,发现data[1]是 88,就返回位置 2—— 告诉你 “88 在第 2 个抽屉里”。

四、顺序表的 “优缺点”:什么时候该用,什么时候不该用?

学完了操作,我们还要知道顺序表的 “适用场景”—— 就像你不会用抽屉柜装冰箱,也不会用行李箱装书本,每个工具都有自己的优缺点。

1. 顺序表的优点:快速 “定位”

因为顺序表底层是数组,元素的存储位置是连续的,而且每个元素的大小固定,所以我们可以通过 “公式” 快速计算出任意元素的位置(比如第 i 个元素的下标是 i-1)。这种 “随机访问” 的能力是顺序表最大的优势 —— 就像你知道抽屉柜第 3 个抽屉的位置,不用翻前面的抽屉,直接就能打开。

比如你想访问顺序表的第 5 个元素,直接用L->data[4]就能拿到,时间复杂度是 O (1)(瞬间完成)。

2. 顺序表的缺点:插入删除 “麻烦”

如果要在顺序表的中间插入或删除元素,就需要挪动后面所有的元素 —— 比如你在有 1000 个元素的顺序表中,往第 2 个位置插入元素,就需要挪动 999 个元素,效率很低(时间复杂度是 O (n))。

这就像你在一个装满书的抽屉柜中间插一本书,需要把后面所有的书都往后挪,书越多,挪起来越费时间。

五、总结:顺序表就是 “带清单的数组”,生活中处处可见

看到这里,你应该能明白:顺序表其实就是给数组加了一个 “长度清单”,让我们能更方便地管理数据。它的逻辑在生活中随处可见 ——

  • 排队买奶茶:每个人按顺序站好,你知道自己是第 5 个(长度),想插入队伍中间需要后面的人往后挪(插入操作),有人离开后后面的人往前补(删除操作);
  • 书架上的书:按顺序排列,你能快速找到第 3 层第 2 本书(随机访问),想在中间插一本书需要挪动后面的书(插入操作)。

数据结构从来不是 “脱离生活的抽象概念”,而是把生活中的 “整理逻辑” 用代码实现出来。下次再遇到 “顺序表”,不妨想想你家的抽屉柜 —— 你就会发现,原来它这么简单!

如果你想进一步实践,可以试着修改文中的代码:比如把elemtype改成char,让顺序表存字符;或者增加 “修改元素” 的功能,给你的 “抽屉柜” 再添一个新技能~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、先搞懂:顺序表到底是什么?像我们生活中的什么?
    • 1. 顺序表和数组的关系:“包装好的数组”
  • 二、为什么需要顺序表?数组不够用吗?
  • 三、手把手学顺序表:5 个核心操作,用代码看懂
    • 1. 第一步:初始化顺序表 —— 给抽屉柜 “贴空清单”
    • 2. 第二步:在末尾添加元素 —— 往最后一个空抽屉放东西
    • 3. 第三步:在指定位置插入元素 —— 把东西插进两个抽屉中间
    • 4. 第四步:删除指定位置元素 —— 把抽屉里的东西拿走,后面的往前挪
    • 5. 第五步:查找元素 —— 根据 “东西” 找它在哪个抽屉
  • 四、顺序表的 “优缺点”:什么时候该用,什么时候不该用?
    • 1. 顺序表的优点:快速 “定位”
    • 2. 顺序表的缺点:插入删除 “麻烦”
  • 五、总结:顺序表就是 “带清单的数组”,生活中处处可见
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档