直接寻址表
概述
直接寻址表(Direct-Address Table, DAT) 是一种最简单的字典实现方式:用一个大小为全域 的数组 ,直接以关键字 作为数组下标来存储和查找元素。它提供了 的最坏情况搜索、插入和删除操作,但当全域 很大而实际存储的元素 很小时,会造成严重的空间浪费。
定义
直接寻址表
设全域 ,直接寻址表是一个数组 ,其中每个位置(称为槽位,slot)对应全域中的一个关键字。若关键字 的元素存在于动态集合 中,则 指向该元素;否则 。
核心思想
直接寻址的本质是:关键字本身就是地址。不需要任何计算或映射,直接用关键字作为数组索引访问。
伪代码
搜索:
DIRECT-ADDRESS-SEARCH(T, k)
return T[k]
插入:
DIRECT-ADDRESS-INSERT(T, x)
T[x.key] = x
删除:
DIRECT-ADDRESS-DELETE(T, x)
T[x.key] = NIL
核心性质
时间复杂度
| 操作 | 最坏情况 | 说明 |
|---|---|---|
| 搜索 | 直接按下标访问数组 | |
| 插入 | 直接按下标写入数组 | |
| 删除 | 直接按下标置 NIL |
所有操作均为最坏情况 ,这是直接寻址表最大的优势。
空间复杂度
- 空间需求为 ,其中 是全域大小。
- 实际存储的元素数量为 。
- 空间利用率为 ,当 时,大量槽位空闲,空间浪费严重。
关键限制
- 全域不能太大:如果全域 很大(例如 64 位整数,),则不可能分配这么大的数组。
- 关键字必须可枚举:关键字必须是有限全域中可直接用作数组下标的值。
- 不适合稀疏数据:当实际存储的元素远少于全域大小时,空间效率极低。
章节扩展
从直接寻址到散列
直接寻址表的空间问题催生了 散列表 的设计思路:
- 直接寻址表:用关键字 直接作为下标 需要 空间
- 散列表:用散列函数 将关键字映射到 大小的数组 只需要 空间( 为实际元素数)
散列函数 将较大的全域映射到较小的表,用少量的空间冲突换取极大的空间节省。
与其他字典实现的对比
| 实现方式 | 搜索 | 插入 | 删除 | 空间 | 适用场景 |
|---|---|---|---|---|---|
| 直接寻址表 | 最坏 | 最坏 | 最坏 | 全域小、元素密集 | |
| 散列表 | 期望 | 期望 | 期望 | 全域大、元素稀疏 | |
| 平衡二叉搜索树 | 最坏 | 最坏 | 最坏 | 需要有序遍历 |