学习笔记:数组与列表(基础数据结构 3.2.1)
欢迎来到这里!本章是你学习计算机科学中高效组织数据的基石。数组和列表是我们存储数据集合最基本、最核心的方式。掌握它们至关重要,因为从排序算法到电子游戏,几乎所有实用的程序都依赖于将数据组织成结构化的组。
如果起初觉得这些概念有些抽象,也不必担心。你可以把数据结构想象成不同类型的文件柜——它们都能存放信息,但有些更适合快速存取(如数组),而有些则更适合灵活扩展(如列表)。
1. 理解数据结构:背景知识 (3.2)
数据结构 (Data structure) 简单来说,就是计算机中组织数据的一种特定方式,旨在让数据能够被高效地使用。在深入探讨数组和列表之前,我们需要理解一个关键区别:
静态数据结构 vs. 动态数据结构
它们的主要区别在于程序运行期间(runtime)其容量的灵活性。
- 静态数据结构 (例如:数组/Array):
在创建结构时,其大小是固定的。它在程序执行期间无法增大或缩小。想象成一个预订好的披萨盒——它正好有8块空间,不多也不少。
优点:内存利用非常高效;存取速度快,因为计算机明确知道每一项数据的存储位置。
缺点:缺乏灵活性。如果空间用完了,你必须创建一个全新的、更大的结构,并将所有数据复制过去。
- 动态数据结构 (例如:列表/List,如 Python 中常见的那样):
其大小是灵活的,可以在程序运行时改变(增大或缩小)。想象成一个购物袋——你可以不断往里添加物品,直到装满为止,或者轻松取出物品。
优点:高度灵活;内存使用量会根据存储的数据动态调整。
缺点:与静态结构相比,存取元素或管理内存的速度可能稍慢,因为元素在内存中可能不是完全连续存储的。
核心要点:当你预先知道数据的最大量时,使用静态结构(数组);当数据量不可预知或不断变化时,使用动态结构(列表)。
2. 数组与列表:核心概念 (3.2.1)
数组和列表的作用都是将多个值存储在一个标识符(名称)下。
什么是数组?
数组 (Array) 是一组数据项的集合,通常具有相同的数据类型,并存储在连续(相邻)的内存位置中。这种结构允许对任何元素进行快速、随机的存取。
类比:想象一排带有编号的邮政信箱。每个信箱(元素)存放一个物品,并且它们按顺序排列。
核心概念:索引 (Indexing)
要访问数组或列表中的某项数据,我们使用它的索引(即它的位置编号)。
- 在大多数计算机科学环境(和编程语言)中,索引从零 (0) 开始。
- 如果一个数组有 \(N\) 个项目,其索引范围从 \(0\) 到 \(N-1\)。
常见错误警告(差一错误/Off-by-One Error):学生经常会忘记索引是从 0 开始的。如果你试图访问一个从索引 1 开始的列表中的第 10 项,你会拿到错误的条目。如果你试图访问等于数组大小的索引(例如:在大小为 5 的数组中访问索引 5),将会导致运行时错误(索引越界/Index Out of Bounds)。
记忆技巧:如果你想要第 1 项,请查询索引 0。如果你想要第 5 项,请查询索引 4。你想要的位置始终是 索引 - 1。
列表定义(及编程背景)
虽然数组通常被视为固定大小且单一类型的结构,但“列表 (List)”在许多高级语言(如教学大纲中提到的 Python)中,被用来描述一种更灵活的、动态的结构,它通常可以容纳混合数据类型并能轻松改变大小。
考试注意事项:在编程考试中,通常可以使用语言内置的列表 (List) 类型来解决问题,除非题目明确要求使用静态数组的特性。
3. 使用一维 (1D) 结构
一维数组/列表代表单行或单序列数据。它只需要一个索引即可定位元素。
分步讲解:访问元素
- 识别数组/列表名称:我们称之为 Student_Names。
- 确定索引:如果我们想要第 3 个名字,索引就是 2。
- 访问元素:
Student_Names[2] 将检索存储在该位置的值。
使用示例:
假设我们有一个测试分数列表:
Scores = [90, 85, 95, 78, 92]
- Scores 的长度为 5。
- 最小索引是 0,最大索引是 4。
- 要找到分数 85,我们访问 Scores[1]。
4. 二维 (2D) 数组和列表的列表 (3.2.1)
通常,数据不仅仅是简单的一行,而是网格或表格。这时二维数组(或列表的列表)就至关重要了。二维数组是指每个元素本身也是一个数组的数组。
类比:想象一个标准的电子表格(如 Excel)。它有行和列。
结构与索引
要访问二维结构中的元素,你需要两个索引:
- 行 (Row) 的索引。
- 该行内列 (Column) 的索引。
格式: 数组名[行索引][列索引]
示例:座位表
想象一个小型电影院座位表(3 行,每行 4 个座位):
Seats = [ [A1, A2, A3, A4], [B1, B2, B3, B4], [C1, C2, C3, C4] ]
- A 行在索引 0,B 行在索引 1,C 行在索引 2。
- 座位 1 在索引 0,座位 4 在索引 3。
如果你想要 B3 座位:
- B 是第 2 行(索引 1)。
- 3 是第 3 个座位(索引 2)。
- 你将访问:Seats[1][2],得到的结果是 'B3'。
二维结构的应用
二维数组经常用于解决涉及以下方面的问题:
- 数学中的矩阵 (Matrices)(例如,用于图形变换)。
- 游戏棋盘(例如:国际象棋、数独、存储地图中的地形)。
- 简单黑白图像的像素数据(其中两个维度分别是高度和宽度)。
你知道吗? 虽然教学大纲将测试限制在两个维度,但编程语言支持多维数组(如用于空间数据的 3D 或 4D),它们都建立在将结构嵌套在彼此内部的同一原则之上。
5. 操作数组和列表
尽管实际语法因语言而异,但你必须理解的基本操作包括:
访问与修改
你可以读取索引处的值,也可以修改索引处的值。
示例:修改分数
如果 Scores[0] = 90,学生将分数提高到了 98,你可以使用赋值语句来修改该值:
Scores[0] = 98
结构迭代
要处理数组中的每一项(或元素),你通常需要使用迭代(循环)。
- 对于一维数组:单层循环即可,通常从索引 0 运行到数组长度(不含该长度)。
- 对于二维数组:你需要嵌套迭代(循环中的循环)。外层循环通常控制行,内层循环控制该行中的列。
分步讲解:遍历二维数组
想象打印出一个 3x4 数组的所有元素:
- 启动外层循环(行 i = 0 到 2)。
- 在内部,启动内层循环(列 j = 0 到 3)。
- 处理 Array[i][j] 处的条目。
- 内层循环结束;移动到下一行(i 加 1)。
- 重复步骤直到所有行处理完毕。
核心要点:数组和列表提供了组织化的存储空间。一维结构使用一个索引;二维结构(网格/表格)使用两个索引(先行,后列)。理解索引(从 0 开始!)对于避免错误至关重要。
***
准备好继续了吗?这些基础结构为你理解下一节中更复杂的数据结构(如记录、队列和栈)奠定了基础!