第一章:通用数据结构 I——物理存储模型(连续与离散)
绪论:数据结构的物理前提
-
数据结构常从逻辑关系讨论,例如线性结构、树结构与图结构。
-
但无论逻辑关系如何设计,数据最终都必须落在 真实存储介质(内存或磁盘) 上。
-
因此在实现层面,任何数据结构都必须回答一个更基础的问题:
数据在物理空间中如何排布?
-
在这一层面,物理排布可以归结为两种基本模型:
连续存储 与 离散存储。
-
数组与链表是这两种模型最直接的代表。
一、连续存储:数组
定义
- 在内存中申请一段 连续地址空间,所有元素大小相同,按固定顺序排列。
机制
- 数组定位依赖地址计算公式:
Address = Base + Index × Size - 只要知道基地址与下标,就可以直接计算目标元素地址。
特征
-
访问复杂度:
O(1)地址可直接计算,不需要遍历路径。
-
**结构刚性:**连续空间必须保持完整,因此成本集中在两类操作:
- **扩容成本:**容量不足时需要重新申请更大的连续空间,并整体搬迁数据。
- 修改成本:在中间插入或删除元素时,需要移动后续元素。
总结
- 连续存储提供 极高访问效率,但扩展与局部修改成本集中。
二、离散存储:链表
定义
- 节点可以分布在内存任意位置,通过 指针连接 建立逻辑顺序。
机制
-
结构:每个节点通常包含两部分
- 数据
- **指针:**指向下一节点(或前后节点)的地址
-
结构通过指针连接形成链式访问路径。
特征
-
访问复杂度:
O(n)访问任意元素需要从头节点开始逐个遍历。
-
结构灵活:
- 插入或删除节点只需要修改指针(在已定位节点的前提下
O(1)) - 不依赖连续地址空间
- 插入或删除节点只需要修改指针(在已定位节点的前提下
-
访问效率受限:
- 每个节点需要额外存储指针,空间利用率较低
- 节点离散分布,指针跳转导致缓存命中率较低
总结
- 离散存储提供更强的结构灵活性,但访问路径依赖指针跳转,实际性能常受缓存局部性限制。
三、硬件现实的影响:连续性的优势
问题
- 理论复杂度只关注
O(1)与O(n),但真实性能还会受到 硬件机制 的影响。
机制**(CPU缓存)**
- 现代 CPU 采用多级缓存(L1/L2/L3)。
- 数据通常以 缓存行 为单位加载,常见大小为 64字节。
影响
- 连续存储的数据位于相邻地址,一个缓存行可加载多个元素,顺序访问命中率更高。
- 链表节点分散在不同地址,指针跳转更容易触发新的缓存行加载。
在真实系统中,两者差距往往 远大于理论复杂度中的常数差异。
工程选择
-
高性能系统通常优先使用:
- 数组
- 数组改造型结构(如动态数组、块状结构)
-
纯链表很少作为核心数据结构。
总结
- 在现代硬件环境下,连续性通常比指针灵活性更具性能优势。
- 许多高性能结构本质上是在 扩展能力 与 局部连续性 之间寻找平衡。
本章总结
- 在物理层面,数据结构只有两种基本模型:连续存储 与 离散存储。
- 连续结构访问效率高,但扩展与局部修改成本集中;离散结构扩展灵活,但访问效率受限。
- 在现代硬件环境下,缓存局部性使连续存储通常具有更高性能。
- 工程中的高性能结构常在 扩展能力 与 局部连续性 之间折中。
下一问题
-
本章解决的是:数据如何存放。
-
当数据规模扩大后,更关键的问题变成:
如何在大量数据中快速定位目标数据?
-
为此系统需要在数据之上建立新的结构:搜索路径。
下一章讨论:索引结构。