“数组可以有共享存储的视图。参考程序用视图四元组”
形式陈述
长度为自然数
固定长度数组的核心操作是读取和原位写入。对合法下标
后一行是重要的保持条件:写入一个位置不应改变其他位置。写入不增加长度;在中间插入一个新元素属于另一个操作,必须说明后续元素如何移动、长度如何变化。
常见实现把数组放在连续内存中。若首槽地址为
在地址和下标可装入常数个机器字、字操作及访问为常数成本的 Word-RAM 模型中,这给出
直觉
数组用“位置可以算出来”代替“沿链接寻找位置”。下标
这也解释了访问与插入的差别。把第
例子与边界
位置和值是两件事
对于
若改为在下标
倒序搬迁保持一个清晰的不变量:已经处理的右侧后缀位于最终位置,尚未处理的左侧原值仍完好。如果改为从左向右,第一次
二维表如何落到一维内存
设二维数组有
例如
数组视图还可能带步长。例如从一个一维数组抽取下标
循环数组依赖分析把这项地址约定用于代码变换:先将每次赋值实例的逻辑访问化为对象与槽位,再区分先写后读、先读后写、先写后写三类冲突。不同视图名不能当作互不别名的证据;共享视图会新增约束,使原本合法的循环交换变成数值错误。
等宽的是槽位,不一定是对象内容
字符串数组可以在每个等宽槽位中保存一个引用。读取第
抽象模型也不替具体语言规定越界行为。检查后报错、返回带失败标记的结果以及不提供安全访问,都属于不同契约。数学表达
长度与容量
动态数组另外维护容量
若容量按倍数增长,从空数组开始连续追加
推论与应用
数组正确性通常分为两层:抽象层规定读取、写入、长度及失败行为;表示层证明每个合法下标映到正确槽位,并且不破坏其他槽位。带容量的实现还需保持
与链表相比,数组擅长按位置访问和连续扫描;链表在已经持有合适节点引用时,可以通过局部链接修改完成部分插入删除。链表的“局部修改快”不包括找到第
二叉堆进一步利用规则形状,把节点关系编码为下标关系;前缀和利用顺序扫描,把区间聚合转化为少数位置的读取。两者节省工作的方式不同,但都建立在位置语义明确、访问契约可靠的基础上。
参考资料
- Pat Morin,Open Data Structures: An Introduction,Athabasca University Press,2013,Chapter 2 与 §2.1 ArrayStack:数组表示、移位、扩容和摊还分析。
- Thomas H. Cormen 等,Introduction to Algorithms,4th ed.,2022,§10.1 与动态表的摊还分析章节:基本表示与成本模型;进一步阅读。