手写 List 容器的动态扩容:从固定大小到无限扩展
·
手写 List 容器的动态扩容实现
动态扩容是 List 容器的核心特性,通过以下步骤实现从固定大小到无限扩展:
1. 核心设计思想
- 初始固定容量:创建时分配固定大小的底层数组
- 扩容触发条件:当添加元素时检测到数组已满
- 扩容策略:创建新数组(通常为原容量的 $1.5$ 或 $2$ 倍)
- 数据迁移:将原数组元素复制到新数组
- 引用更新:将底层数组引用指向新数组
2. Python 实现代码
class DynamicList:
def __init__(self, initial_capacity=10):
self._capacity = initial_capacity # 当前容量
self._size = 0 # 当前元素数量
self._data = [None] * initial_capacity # 底层存储数组
def __len__(self):
return self._size
def __getitem__(self, index):
if index < 0 or index >= self._size:
raise IndexError("Index out of range")
return self._data[index]
def __str__(self):
return "[" + ", ".join(str(x) for x in self._data[:self._size]) + "]"
def append(self, value):
# 检测是否需要扩容
if self._size == self._capacity:
self._resize(int(self._capacity * 1.5) + 1) # 1.5倍扩容
# 添加新元素
self._data[self._size] = value
self._size += 1
def _resize(self, new_capacity):
# 创建新数组
new_data = [None] * new_capacity
# 复制旧数据
for i in range(self._size):
new_data[i] = self._data[i]
# 更新引用和容量
self._data = new_data
self._capacity = new_capacity
print(f"扩容至 {new_capacity} 容量") # 调试信息
# 测试用例
if __name__ == "__main__":
lst = DynamicList(initial_capacity=3)
print("初始状态:", lst)
print("添加元素 1, 2, 3...")
lst.append(1)
lst.append(2)
lst.append(3)
print("当前状态:", lst)
print("添加元素 4 (触发扩容)...")
lst.append(4)
print("扩容后状态:", lst)
print("添加元素 5, 6, 7...")
lst.append(5)
lst.append(6)
lst.append(7)
print("当前状态:", lst)
3. 关键特性说明
-
时间复杂度:
- 添加元素平均时间复杂度 $O(1)$
- 扩容操作时间复杂度 $O(n)$
- 均摊分析后添加操作仍为 $O(1)$
-
扩容因子选择:
- 使用 $1.5$ 倍扩容(示例代码)
- 也可采用 $2$ 倍扩容(常见实现)
- 数学证明:当扩容因子 $>1$ 时可保证均摊时间复杂度为 $O(1)$
-
内存管理:
- 旧数组在扩容后由垃圾回收器自动回收
- 避免频繁扩容:根据预估数据量设置合理初始容量
4. 执行结果示例
初始状态: []
添加元素 1, 2, 3...
当前状态: [1, 2, 3]
添加元素 4 (触发扩容)...
扩容至 4 容量
扩容后状态: [1, 2, 3, 4]
添加元素 5, 6, 7...
扩容至 6 容量
当前状态: [1, 2, 3, 4, 5, 6, 7]
此实现完整展示了动态扩容的核心机制,可根据需求扩展插入、删除等功能,同时保持高效的内存管理和时间复杂度特性。
更多推荐
所有评论(0)