Skip to content

数组

Array

以连续整数下标支持随机访问的有限序列结构。

条目类型
模型

形式陈述

长度为 n 的数组可抽象为定义在自然数初始段上的函数

A:{0,1,,n1}V,

支持两种基本操作:按下标读取 A[i],与按下标更新 A[i]x。作为抽象数据类型,数组只承诺这一定长索引映射的接口;连续内存是其典型实现——元素大小为 s、基址为 b 时,A[i] 位于地址 b+is,因此在随机访问机模型下单次读写为 O(1)。二维数组按行主序存放时,m 列的 A[i][j] 位于线性偏移 im+j 处。在中间位置插入或删除需要搬移其后全部元素,代价 O(n);改变长度与扩缩容量属于动态数组增加的另一层接口。

直觉

数组是“以自然数初始段为定义域的有限函数”在机器上的直接化身:下标算术取代了查找,这就是随机访问快的全部原因——地址由一次乘加算出,与 n 无关。对比链式结构,访问第 i 项必须沿指针走 i 步;数组用“位置可计算”换来了“长度难伸缩”,这一取舍贯穿数据结构设计的始终。抽象与实现宜分开看:接口层面数组只是索引映射,内存连续性属于实现层,但由它带来的缓存局部性正是工程中数组常胜过指针结构的原因。

数组索引与地址偏移示意图
例子与边界

数组 [a0,a1,a2] 的合法下标是 0,1,2,访问 A[3] 越界——抽象函数在 3 处根本无定义,而实现层面可能读到无关内存,这是大量安全漏洞的来源。行主序的具体一例:23 列的数组中,A[1][2] 的线性偏移为 13+2=5,恰是最后一个元素。

边界情形多源于“数组”一词的多义。定长数组与动态数组不是同一个 ADT:后者添加了改变长度的操作,其尾部追加的 O(1)摊还分析意义下的,单次搬迁仍是 Θ(n)O(1) 随机访问依赖顺序存储:若用链表实现同一接口,按下标读取退化为 O(i)。下标从 0 还是 1 开始只是约定,但混用两种约定是差一错误的高发地。

长度为 n 的零基数组合法索引为 0,,n1,地址公式为 base + i * sizeof(T)。越界访问在低级语言中不自动产生合法元素;尾部追加、容量翻倍及其摊还证明由动态数组条目统一处理。

推论与应用

数组是大量上层结构的底座:二分查找依赖 O(1) 定位中点;二叉堆用下标算术隐式编码完全二叉树;前缀和与差分技巧在数组上完成区间统计与批量更新。矩阵与表格数据按行主序或列主序落成数组,图的邻接矩阵也用二维下标把边查询化为常数时间;哈希表的桶、原地排序的工作区以及强调顺序扫描与缓存命中的算法同样以连续数组承载。动态数组另加长度和容量状态,其尾部追加只给摊还 O(1),不改变本页定长数组的接口中心。

“随机访问 O(1)”必须绑定到能在一个机器字中表示下标并按字寻址的 RAM 模型。简洁位向量仍呈现数组式 bit 序列,却把空间压到接近信息下界并额外支持 rank/select;在外存模型中,顺序扫描和随机访问应按块传输次数计费,缓存无关模型又要求算法在不知道块大小 B 与缓存容量 M 时维持良好局部性。这些模型解释连续布局的不同成本,不属于数组 ADT 的定义。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022, Chapter 10。
  • Robert Sedgewick and Kevin Wayne, Algorithms, 4th ed., Addison-Wesley, 2011, §1.4。
关系图谱68 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系