跳转至

P2-9.4 补充学习:第一次阅读传统数据结构的方法

Section ID: P2-9.4 Version: v2026.07.23

在 P2-9.1 中,我们把数据结构看成“承载数据的形状”和“处理这些数据的方法”。但一旦开始学习数据结构,很多陌生名字会突然一起出现。

数组(array)、链表(linked list)、栈(stack)、队列(queue)、树(tree)、图(graph)、哈希表(hash table)。

这里说明的是 如何阅读传统数据结构名称的标准。本节会把数组、链表、栈、队列、树、图、哈希表这些名称,重新按“问题中心”而不是按“实现中心”来整理。

如果一开始就试图用实现方式去背这些名字,会觉得很难。这个补充学习先看的是:每一种结构最初是为了让什么问题更容易?

如果你很久以前学过编程基础,或者先把 Python 当成实践工具来接触,这些数据结构名称会显得更陌生。因为 Python 的列表和字典已经能方便地处理很多事,人就会自然地怀疑:像数组、链表、栈、队列这样的传统名称,到底还有没有必要。

但只要 AI 实践稍微扩展开一点,这些名称就会再次回来。数据集看起来像表,token 要按顺序处理,标签要按 key-value 映射来管理,而搜索和推荐又会用到关系与索引结构。传统数据结构不是 旧语法,而更像是一种阅读数据的基础语言。

所以本节首先整理的是:当数组、栈、队列、图这些名字一下子都很陌生时,这个名字让什么问题更容易?

先带走的内容

本节把必需复习和扩展背景放在一个地方。第一次读时,只要先抓住下面五个 必需 项目即可,其余部分以后再回来读也没有问题。

分类 先带走的内容
必需 数组是一种按位置读取值的结构
必需 栈是一种“最后放进去的先拿出来”的规则
必需 队列是一种“最先放进去的最先拿出来”的规则
必需 树表达层级关系,图表达连接关系
必需 在 Python 的列表和字典背后,仍然有更一般的数据结构问题
扩展 链表的连接直觉
扩展 哈希表的内部组织直觉
扩展 实现细节、复杂度、内存布局等后续学习主题
术语 本节先要抓住的含义
array 一种按顺序读取带编号值槽的结构
linked list 一种每个项目通过指向下一个项目来延续的结构
stack 一种以“最后放进去的先拿出来”为规则中心的结构
queue 一种以“最先放进去的最先拿出来”为规则中心的结构
hash table 一种为了按 key 快速找到值而组织起来的结构

阅读标准:第一次阅读传统数据结构的方法

  • 能把传统数据结构名称和它们解决的问题连接起来阅读。
  • 能在入门层面区分线性结构、非线性结构和基于 key 的结构。
  • 能说明 Python 的列表和字典与传统数据结构说明并不完全相同,但仍然可以借用这些直觉来理解。
  • 能说明在 AI 实践里,数据集、token 列表、标签映射、文档关系、搜索索引等结构会要求不同的数据结构直觉。

先要抓住的标准

在这个补充学习里,最先要抓住的标准是:数据结构名称,是贴在一个代表性问题上的标签

名称 先抓住的问题
array 某个位置上的值是什么?
stack 最后放进去的东西会先出来吗?
queue 最先放进去的东西会先出来吗?
tree 有没有父子关系?
graph 什么和什么相连?
hash table 我们是不是想按 key 快速找到值?

也就是说,本节优先阅读的是:这个名字让什么问题变得容易,而不是实现细节。

背景

传统数据结构有时会在 Python 语法之前学习,但在再学习路径里,反而更自然的是稍后再回来看。因为等你已经用过列表和字典之后,再重新读数组、栈、队列、树、图,就更容易抓住:这个名字到底让什么问题更容易?

所以本节的组织方式,是先问 为什么需要这种结构,而不是先堆实现细节。目标不是背下一张名称清单,而是读出它们和 AI 实践场景的连接。

三个标准

标准 为什么重要 本节需要达到的理解程度
为什么要重新看传统数据结构 它能帮你恢复 Python 语法背后更一般的思考方式 抓住一点:数据结构名称不是旧语法,而是问题的语言
数据结构名称代表什么 它让你先看什么问题被简化,而不是先背存储方法 理解每个名称都对应不同的代表性问题
它们和 Python 数据类型的关系 它让你把已经学过的列表和字典连接到更宽的结构直觉上 理解列表和字典也延续着更早的数据结构思想

主要学习内容

为什么要在后面重新看传统数据结构

在 P2-8 中,我们先看了 Python 语法。这个顺序是有意的。因为如果一开始就进入数据结构理论,实现细节会过多,也会偏离 AI 再学习的目的。

但只靠 Python 语法,很难回答下面这些问题。

  • 为什么列表适合按顺序处理?
  • 为什么字典适合按名字或 ID 找值?
  • 为什么有些数据应该看成表,有些数据应该看成图?
  • 为什么即使是同样的数据,一旦目的变成搜索、推荐、分类或可视化,结构也会变化?

传统数据结构正是这些问题背后的背景知识。本节不是实现课程,而是一个补充学习:帮助你在看到这些数据结构名称时,脑中能先出现最小地图。

数据结构名称代表的是问题

如果把数据结构当成一串名称去背,很快就会混乱。更好的方式,是先看每个名称所代表的问题。

数据结构 代表性问题 先想到的场景
array 某个位置上的值是什么? 按顺序摆放的数字、向量、像素
linked list 下一个值在哪里? 项目彼此指向下一个项目的结构
stack 最后放进去的东西会先出来吗? 撤销、调用流程、临时存放
queue 最先放进去的东西会先被处理吗? 工作队列、请求处理
tree 有没有父子关系? 文件夹、分类体系、决策流程
graph 什么和什么相连? 朋友关系、链接、知识图谱
hash table 我们是不是想按 key 立刻找到值? 按 ID 找用户、统计词频

这张表不是严格分类图,而是一张给初学者的地图。真实编程语言里的数据结构,内部通常更复杂。比如 Python 的字典,从使用角度看是一个 key 找到 value 的映射,但从实现角度看又和哈希表相连。

阅读数据结构时,应先看操作,再看名称。

常见操作 问题 对应的数据结构直觉
access 我们是不是想立刻看到某个位置或某个 key 的值? array、dictionary
insert 我们是不是经常要加入值? list、linked list、queue
delete 我们是不是经常要移除值? list、linked list、stack、queue
search 我们是不是需要找到目标值? array、hash table、tree
traversal 我们是不是要按顺序扫完整个结构? list、tree、graph
relation movement 我们是不是要移动到下一个连接对象? tree、graph

这张表也不是绝对答案。即使是同一种数据结构,实际性能也会随着实现方式和数据规模而变化。这里更关注的是:遇到什么问题时,应该先想起什么直觉。

选择数据结构时先问的三个问题

选择数据结构时,先检查下面三个问题。

第一,数据有没有顺序?

如果像句子里的 token、按时间进入的日志、图像像素那样,顺序和位置很重要,就需要列表、数组、序列的直觉。

第二,是不是需要按名字或 ID 找?

如果你需要按用户 ID 找用户信息、按标签编号找标签名称,或者统计词频,就需要字典、映射、哈希表的直觉。

第三,是不是需要沿着对象之间的关系往前走?

如果你需要追踪文档之间的链接、人与人的关系、概念之间的连接,就需要树或图的直觉。

这三个问题在 AI 实践里也经常出现。

问题 AI 实践例子 先想到的结构
顺序重要吗? token 列表、时间序列数据、图像像素 list、array、sequence
需要按 key 找吗? 标签映射、词频、配置值 dictionary、hash table
需要沿着关系往前走吗? 文档链接、知识图谱、推荐关系 tree、graph

如果把这三个问题再更短地归纳一次:

先问什么 为什么需要
顺序重要吗? 为了选定线性结构直觉
需要按名字或 ID 找吗? 为了选定基于 key 的结构直觉
需要沿着关系往前走吗? 为了选定非线性结构直觉

详细学习内容

线性结构:把数据看成一条线

线性结构是把数据看成一条顺序线的结构。数组、链表、栈、队列都接近这一类。

看线性结构时,先问这些问题。

  • 顺序重要吗?
  • 位置编号重要吗?
  • 是从前面开始处理吗?
  • 是从后面拿出来吗?
  • 中间会频繁插入或删除吗?

数组(array)

数组是一种通过位置来处理同类值的结构。看数学里的向量时,位置直觉很重要;看图像处理里的像素时,位置直觉也很重要。

这里把数组理解成 带编号的格子

位置 0 1 2 3
10 20 30 40

数组带来的是“按位置访问”的直觉。所以在学习 NumPy 数组、向量、矩阵时,它会再次出现。

理解数组时,重要的一点是:位置本身有意义。 例如 embedding 向量里的每个格子装着一个数字,但这些数字的位置关系会参与模型计算。图像也是一样,如果像素值任意散开,就不再是图像。值属于哪个位置是重要的。

Python 列表也能按位置取值,所以它看起来像数组。

问题场景:在一个像数组那样“位置重要”的结构里,你想立刻取出某个格子的值。 输入(input):一个按顺序保存四个数字的列表,以及索引 2。 期望输出(output):打印第三个位置上的值 30。 要确认的概念:看到数组直觉的核心不是值本身,而是通过位置(index)访问。

1
2
3
# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
values = [10, 20, 30, 40]
print(values[2])

但不能把 Python 列表和传统数组看成完全一样。Python 列表是一种保存对象引用的动态结构,而 NumPy 数组则是一种为了数值计算而把同类数字紧密存放的结构。现在先带走共同直觉 按位置访问 就够了。

链表(linked list)

从这里开始的链表部分,以及后面的哈希表部分,更接近 扩展 阅读。如果数组、栈、队列、树、图的代表性问题已经抓住了,这一部分可以留到后面再读。

链表是一种“每个项目都指向下一个项目”的结构。它不像数组那样假设每个格子都排在连续的位置上,而是用 这个项目后面是那个项目 这样的思路来组织。

这里可以这样理解它。

Kim -> Lee -> Park -> None

这个例子并不表示它和真实的 Python 列表实现相同。它展示的是这样一种想法:存值的节点(node)会指向下一个项目。

链表在以后理解图时也有帮助。因为“值彼此指向”的感觉,会延续到关系结构里。

链表的重要性在于,它打开了这样一种思路:数据不一定非要放在连续格子里。 如果数据可以指向下一个对象,那么一条顺序线也可以通过连接来表达。

不过在 Python 入门阶段,你通常不需要亲自实现链表。这里更多是把它作为背景,帮助你以后遇到 pointer、node、link 这些词时不要害怕。

栈(stack)

栈是一种“最后放进去的先拿出来”的结构。通常叫 LIFO。

例如叠盘子时,最上面最后放的盘子会先被拿走。

1
2
3
4
5
push A
push B
push C
pop  -> C
pop  -> B

栈经常出现在撤销、函数调用流程、括号检查等编程例子里。现在先记住规则 最后放进去的先出来,而不是实现方式。

在 AI 实践里,栈的直觉也会间接出现。比如代码执行出错时,traceback 会显示函数调用流程。这时,一个函数调用另一个函数,而后进入的调用先结束 这种感觉就和栈连在一起。

队列(queue)

队列是一种“最先放进去的最先处理”的结构。通常叫 FIFO。

它很像排队时先到的人会先被处理。

1
2
3
4
5
enqueue A
enqueue B
enqueue C
dequeue -> A
dequeue -> B

队列经常出现在请求处理、任务队列、消息处理和数据流场景里。在 AI 服务中,它也会连接到:用户请求按顺序处理,或后台任务被放入等待队列。

从服务视角看,队列尤其重要。如果模型调用耗时很长,或图像生成这类请求需要较长时间,就可能不会立刻处理,而是先放进任务队列。在这种情况下,queue 不只是一个数据结构名称,它还连接到一个运营问题:请求将按什么顺序被处理?

非线性结构:不是一条线,而是关系

非线性结构不会只把数据看成一条顺序线。树和图就是最典型的例子。

看非线性结构时,先问这些问题。

  • 有没有父子关系?
  • 多个对象之间是不是互相连接?
  • 只有一条路径,还是有多条路径?
  • 是否需要沿着关系移动?

树(tree)

树是一种表达层级的结构。它通常被解释为从一个根(root)开始,再向下分枝。

文件夹结构就是一个很容易理解的例子。

1
2
3
4
5
book
├─ part-01
│  └─ chapter-01
└─ part-02
   └─ chapter-09

树经常用于解释分类体系、文件系统、决策树和文档结构。一个学习文档的目录,也很接近从 Part 到 Chapter 再到 Section 的树结构。

看树时,重要的是这样一种感觉:一个对象下面会有多个下级对象。 例如,一本书的目录里,Part 下有 Chapter,Chapter 下有 Section。在这种结构里,从上往下走,范围会逐渐收窄。

在 AI 中,也有像决策树这样的模型,会把判断过程分叉;还有把文档标题和小标题结构读成层级的任务。在搜索系统里,类别分类和文档结构理解也会用到树的直觉。

图(graph)

图表达的是对象之间的连接。在图里,对象叫 node,连接叫 edge。

树可以看成比图更受限制的结构。树通常层级很清楚,而图允许多个方向的连接。

1
2
3
4
Kim -- Lee
Kim -- Park
Lee -- Choi
Park -- Choi

图在理解朋友关系、网页链接、交通网络、知识图谱、推荐系统和搜索结构时都很重要。P2-9.3 会从关系表达的角度单独讨论图。

图会在 关系不能只整理成一条线或一层树 的时候变得必要。朋友关系里,一个人可以连向很多人;文档链接也能朝多个方向延展。知识图谱则会用 node 和 edge 来表达概念、对象、属性之间的关系。

理解了图之后,像 搜索为什么会沿着链接扩展?推荐为什么要看相似用户或相似项目?RAG 里文档片段为什么可能有关系? 这类问题,就更容易看明白。

基于 key 的结构:靠标签来找

基于 key 的结构里,通过什么 key 找到它值在第几个位置 更重要。

在 Python 中,最熟悉的例子就是字典(dictionary)。

问题场景:你想通过类似名字标签的 key 直接找到分数,而不是按顺序位置去找。 输入(input):一个字典,键是姓名,值是分数。 期望输出(output):打印 key 为 Kim 的分数 82。 要确认的概念:看到基于 key 的结构核心在于按 key 找值,而不是按位置找值。

1
2
3
4
5
6
7
8
# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
score_by_name = {
    "Kim": 82,
    "Lee": 75,
    "Park": 91,
}

print(score_by_name["Kim"])

这段代码就是通过姓名这个 key 来找到分数。

在传统数据结构里,哈希表经常和基于 key 的搜索连在一起。哈希表可以解释成:一种把 key 转成某个位置,再借此找到值的结构。但真实实现会涉及冲突处理、内存布局、扩容等细节,所以这里不深入展开。

在入门阶段,hash 可以粗略理解为:把一个 key 转成便于找到存储位置的值的过程。 例如,你不必从头到尾比较 "Kim" 这个名字直到找到它,而是先把这个名字转换成某个数字位置,再去那里找到值,这就是哈希表的基本直觉。

真实哈希表必须处理“不同 key 落在同一个位置”的冲突,也必须在数据增多时调整内部尺寸。本节不处理这些实现细节。在当前正文里,不单独扩展冲突处理和 re-sizing,重要的是先知道:在字典这种“按 key 找值”的结构背后,存在着哈希表的直觉。

这里先记住下面这些就够了。

  • 列表适合按顺序处理。
  • 字典适合按 key 查找。
  • 哈希表和“按 key 查找值”的实现方式相连。

案例与示例

Python 的列表和字典,怎样连接到传统数据结构

先学 Python 时,列表和字典会让人感觉非常方便。所以很容易出现这样的想法:是不是只知道这两种就够了?

但一旦知道传统数据结构名称,你就能更准确地读出代码意图。

Python 里看到的代码 数据结构直觉 阅读方法
items = [] list、sequence 把多个项目按顺序收集起来
items.append(x) 也可能带有 stack 直觉 把值加到后面
items.pop() stack 直觉 把最后一个值拿出来
collections.deque() queue、deque 从两端放入和取出
{key: value} mapping、hash table 直觉 按 key 找值
{node: [neighbors]} graph 邻接表直觉 按节点保存它连接的对象

Python 对象和传统数据结构并不是完全一一对应的。但传统数据结构直觉能帮助你在读 Python 代码时,更快看出:这段代码到底在打算采用什么处理方式?

案例 1. 学会 Python 列表和字典之后,数据结构是不是就结束了?

假设一位学习者已经熟悉了 Python 的列表和字典,于是开始想:像数组、栈、队列、树、图这些名字,真的还需要吗? 在小型练习里,这种感觉很真实。

但当工作规模扩大后,问题会改变。token 必须按顺序处理;任务请求要像排队一样被处理;标签名称要按 key 查找;文档链接和推荐关系要作为连接结构来阅读。也就是说,即使你在使用 Python 的基本数据类型,背后的数据结构直觉仍然一直在工作。

这也是本补充学习重新拿出这些传统名称的原因。目标不是实现课程,而是读出:这个名字最初是为了解决什么问题而出现的? 一旦能这样读,你在 Python 代码里早已看到的列表和字典,也会变成更大地图里的一部分。

可检查的结果是:你能不能把 AI 实践场景重新改写成结构问题。如果你能区分 这是顺序问题吗?这是 key 查找问题吗?这是关系追踪问题吗?,那么你就已经开始把数据结构名称当成“解释工具”,而不是“术语清单”来使用了。

以不同方式保存同样的材料

下面的数据,展示的是同一份学生分数从三种视角来保存。如果想按顺序处理,列表会更方便;如果想按名字查找,字典会更方便;如果想表达朋友关系,就需要更接近图的结构。

问题场景:想用同一份学生材料比较按顺序访问、按 key 查找、沿关系追踪。 输入(input):scoresscore_by_namerelation_graph。 期望输出(output):第一个分数、Kim 的分数、Kim 的直接连接对象。 要确认的概念:问题是位置、key 查找还是关系,决定了结构会怎样变化。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
scores = [82, 75, 91]
score_by_name = {
    "Kim": 82,
    "Lee": 75,
    "Park": 91,
}
relation_graph = {
    "Kim": ["Lee", "Park"],
    "Lee": ["Kim"],
    "Park": ["Kim"],
}

print("list by position:", scores[0])
print("dict by key:", score_by_name["Kim"])
print("graph by neighbor:", relation_graph["Kim"])

这三个例子虽然都用 Python 语法来写,但分别调用了不同的数据结构直觉。第一个是顺序,第二个是基于 key 的查找,第三个是关系表达。

练习与示例

可以直接运行的最小 Python 例子

下面这些例子不是为了把传统数据结构完整实现出来,而是用来确认每种结构大致有什么行为直觉。你可以直接在 Colab 代码单元或本地 Python 文件里运行。

数组直觉:按位置访问

Python 列表和传统数组并不完全相同,但很适合用来确认“按位置访问”的直觉。

问题场景:你想亲自确认数组直觉下读取值、修改值的基本动作。 输入(input):一个包含四个数字的列表、两次按索引读取和一次值修改。 期望输出(output):依次打印第一个值、第三个值,以及修改后的完整列表。 要确认的概念:确认在像数组那样的结构里,值是按位置读取、按位置修改的。

1
2
3
4
5
6
7
8
# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
values = [10, 20, 30, 40]

print(values[0])
print(values[2])

values[1] = 25
print(values)

这个例子的重要点在于:每个值都有位置,而你可以通过位置取出或改写它。

链表直觉:沿着下一个项目前进

链表展示的是“一个项目指向下一个项目”的想法。这里不创建类,而是只用字典来确认 node 直觉。

问题场景:你想看一个例子,值不是放在连续格子里,而是通过“下一个项目”被串起来读取。 输入(input):三个带有 valuenext 的节点字典。 期望输出(output):依次打印 KimLeePark。 要确认的概念:看到链表直觉不在编号位置,而在指向下一个节点的链接。

1
2
3
4
5
6
7
8
9
# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
third = {"value": "Park", "next": None}
second = {"value": "Lee", "next": third}
first = {"value": "Kim", "next": second}

node = first
while node is not None:
    print(node["value"])
    node = node["next"]

这个例子真的在跟着 Kim -> Lee -> Park -> None 的流程走。关键不是值是不是在连续格子里,而是存在一条能移动到下一个项目的连接。

栈直觉:最后放进去的先拿出来

通过 Python 列表的 append()pop(),就能确认栈的直觉。

问题场景:你想直接看到“最后放进去的值先出来”这一栈规则。 输入(input):往空列表里依次放入 "A""B""C",再拿出两个值的代码。 期望输出(output):打印 "C""B",以及剩下的列表。 要确认的概念:确认栈的核心规则是 LIFO。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
stack = []

stack.append("A")
stack.append("B")
stack.append("C")

print(stack.pop())
print(stack.pop())
print(stack)

最后放进去的 "C" 最先出来。这就是 LIFO 的直觉。

队列直觉:最先放进去的先被处理

队列的流程是“后面加入、前面取出”。在 Python 里,可以通过 collections.deque 简单确认这种直觉。

问题场景:你想直接看到“最先放进去的值最先出来”这一队列规则。 输入(input):把 "A""B""C" 放进 deque,再从前面拿出两个值的代码。 期望输出(output):打印 "A""B",以及剩下的队列。 要确认的概念:确认队列的核心规则是 FIFO。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
from collections import deque

queue = deque()

queue.append("A")
queue.append("B")
queue.append("C")

print(queue.popleft())
print(queue.popleft())
print(queue)

最先放进去的 "A" 最先出来。这就是 FIFO 的直觉。

树直觉:沿着父与子往下走

树表达的是父子关系。下面这个例子把一本书的目录表达成小型树。

问题场景:你想看一个小数据例子,像书目录那样从上往下展开层级。 输入(input):一个由 titlechildren 组成的嵌套字典。 期望输出(output):按层级打印书名、各个 Part 标题,以及它们下面的 Chapter 名称。 要确认的概念:确认树是一种“父项下面挂着子项”的层级结构。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
book = {
    "title": "study-book",
    "children": [
        {
            "title": "Part 1",
            "children": ["Chapter 1", "Chapter 2"],
        },
        {
            "title": "Part 2",
            "children": ["Chapter 8", "Chapter 9"],
        },
    ],
}

print(book["title"])
for part in book["children"]:
    print("-", part["title"])
    for chapter in part["children"]:
        print("  -", chapter)

在树的例子里,范围会随着你从上往下走而逐渐变窄。当数据具有清晰层级,例如书、Part、Chapter 时,就需要这种直觉。

图直觉:沿着已连接的对象前进

图表达的是对象之间的连接。下面这个例子把人际关系写成类似邻接表的形式。

问题场景:你想从图结构里取出某个人直接连接的邻居。 输入(input):一个按人保存朋友列表的邻接表字典。 期望输出(output):打印 Kim 的邻居列表,以及每一条连接句子。 要确认的概念:看到在图里,比顺序更重要的是已连接对象的列表。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
graph = {
    "Kim": ["Lee", "Park"],
    "Lee": ["Kim", "Choi"],
    "Park": ["Kim"],
    "Choi": ["Lee"],
}

print(graph["Kim"])

for friend in graph["Kim"]:
    print("Kim is connected to", friend)

在图里,比起 它在第几个位置?,更重要的是 它和谁相连? 这种直觉会在推荐、搜索和链接分析中再次出现。

哈希表直觉:按 key 找值

从使用角度看,Python 字典就是一种按 key 找值的结构。即使不解释内部实现,它也很适合确认哈希表直觉。

问题场景:你想用标签式的 key 来读一个值、加入一个新值,而不是按顺序扫过去。 输入(input):一个以姓名为 key、分数为 value 的字典,以及新增一个条目。 期望输出(output):打印 Kim 的分数,以及加入新条目后的字典。 要确认的概念:确认在基于 key 的结构里,重要的是通过什么名字找到它,而不是它排在第几个位置。

# 这个例子用来确认传统数据结构如何改变存储方式和访问方式。
score_by_name = {
    "Kim": 82,
    "Lee": 75,
    "Park": 91,
}

print(score_by_name["Kim"])

score_by_name["Choi"] = 88
print(score_by_name)

这个例子的重要点在于:值是通过 "Kim" 这样的 key 找到的,而不是通过顺序扫描找到的。

会在 AI 实践中再次遇到的数据结构

在 AI 实践里,即使数据结构名称没有直接出现,你也会不断遇到类似思想。

AI 实践场景 数据结构直觉
输入多个句子 list、sequence
按顺序处理 token array、sequence
把标签编号变成标签名称 dictionary、mapping
去掉重复词 set
处理表格数据 table、DataFrame
跟随文档之间的链接 graph
收集 embedding 做搜索 array、index、search structure
按顺序处理任务请求 queue

这个补充学习不是让你实现所有结构,而是帮助你在以后阅读 AI 实践文档时,分辨“顺序结构”“基于 key 的结构”“沿关系前进的结构”。

容易误解的点

第一,Python 列表并不完全等于传统数组。

它们都能按位置取值,但 Python 列表可以动态改变大小,也能容纳不同种类的对象。NumPy 数组则拥有更适合数值计算的严格结构。所以与其断言 list 就是 array,不如理解成 list 提供了类似 array 的位置访问直觉 更安全。

第二,字典和哈希表有关,但字典并不等于完整的哈希表说明。

Python 字典是一个按 key 找 value 的映射对象。内部实现与哈希表直觉相连,但使用说明和实现说明必须区分开。

第三,树和图并不是完全分离的两个世界。

树是一种层级清晰的关系结构,而图是一种更一般的连接结构。这里的区分是:树是 父子关系很强的结构,图是 表达多个对象之间连接的结构

第四,数据结构不只是为了性能。

它也会显露代码的意义。使用列表时,按顺序处理 的意图会显露出来;使用字典时,按 key 查找 的意图会显露出来;使用图结构时,沿着关系前进 的意图也会显露出来。

检查清单

  • 能不能用代表性问题解释数组、栈、队列、树、图、哈希表?
  • 能不能说明为什么在学过 Python 语法之后,仍然需要重新阅读传统数据结构名称?
  • 能不能说明当顺序、key 或关系分别重要时,选择结构的直觉是什么?
  • 能把数组解释成按位置处理值的结构。
  • 能把链表解释成每个项目指向下一个项目的结构。
  • 能用 LIFO 解释栈,用 FIFO 解释队列。
  • 能区分树是层级结构,图是关系结构。
  • 能说明字典和哈希表与基于 key 的查找相连。
  • 能说明在 Python 方便语法背后,传统数据结构直觉仍然在发挥作用。
  • 能运行数组、链表、栈、队列、树、图、字典的 Python 例子,并解释输出流程。
  • 能不能先区分 这是顺序问题吗这是 key 查找问题吗这是关系追踪问题吗

来源与参考资料

  • NIST, Data structure, Dictionary of Algorithms and Data Structures,确认日期:2026-07-20。用于确认把传统数据结构名称读成组织数据方式的基本定义。
  • NIST, Abstract data type, Dictionary of Algorithms and Data Structures,确认日期:2026-07-20。作为按提供的行为而非实现来说明 stack、queue 等结构的依据。
  • Python Software Foundation, Data Structures, Python 3.14.6 documentation,确认日期:2026-07-20。用于确认 Python list 与 dictionary 语法怎样连接到传统数据结构直觉。