C++ 自定义循环数组类设计与应用解析(CycleArray)


一、背景与目标

在性能敏感或内存控制要求高的场景下,标准库中的 deque 或 vector 未必最合适。实现一个自定义的循环数组结构,可以带来更大的灵活性与控制力。


二、CycleArray 类的功能设计

CycleArray<T> 是一个模板类,提供如下功能:

  • 支持头尾插入与删除(双端队列)
  • 自动扩容与缩容(动态数组)
  • 支持访问首尾元素、判断是否空满

构造函数支持初始容量设定,内部以 unique_ptr<T[]> 管理资源。


三、实现关键与代码解析

1. 核心成员变量设计

std::unique_ptr<T[]> arr;
int start; // 闭区间,指向第一个有效元素
int end;   // 开区间,指向可插入位置
int count; // 当前元素数量
int size;  // 当前数组容量

2. 插入与删除逻辑

addFirst()

if (isFull()) resize(size * 2);
start = (start - 1 + size) % size;
arr[start] = val;
count++;

removeFirst()

arr[start] = T();
start = (start + 1) % size;
count--;
if (count > 0 && count == size / 4) resize(size / 2);

注:因为 start 是闭区间,需要先操作再移动。

addLast() 与 removeLast() 同理


四、自动扩缩容逻辑

void resize(int newSize) {
    std::unique_ptr<T[]> newArr = std::make_unique<T[]>(newSize);
    for (int i = 0; i < count; ++i)
        newArr[i] = arr[(start + i) % size];
    arr = std::move(newArr);
    start = 0;
    end = count;
    size = newSize;
}
  • 使用取模操作保持循环特性;
  • 复制时保持顺序不变;
  • 设置新指针并更新容量信息。

五、示例与调试输出

CycleArray<int> q;
q.addLast(1);
q.addLast(2);
q.addFirst(0);
q.removeLast();
cout << q.getFirst(); // 输出 0

建议添加调试函数:

void print() const {
    for (int i = 0; i < count; ++i)
        std::cout << arr[(start + i) % size] << ' ';
    std::cout << '\n';
}

六、设计哲学与易错点提示

区间设计:闭/开

指针 类型 行为
start 闭区间 指向当前第一个元素
end 开区间 指向插入尾部位置

易错点

  • removeFirst() 顺序不能反;
  • 缩容要判断 count > 0,防止无限缩;
  • 忘记使用 % size 保证循环;

七、扩展建议

  • 重载 operator[] 实现下标访问;
  • 添加迭代器支持;
  • 提供容量、索引边界检查接口;
  • 可与 std::deque 封装统一接口风格。

八、总结

CycleArray 是一个结构紧凑、逻辑严密的容器实现练习例子,特别适合面试或底层结构学习。理解其中的“闭开区间”策略、循环与扩缩容机制,将有助于写出更健壮的自定义容器代码。


文章作者: QT
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 QT !
赏
 本篇
C++ 自定义循环数组类设计与应用解析(CycleArray) C++ 自定义循环数组类设计与应用解析(CycleArray)
本文介绍一个支持动态扩容、双端插入删除的循环数组类 CycleArray 的实现与使用,并深入分析设计背后的区间语义与优化细节。
下一篇 
C++ 算法考试应试指南与 STL 模板精选 C++ 算法考试应试指南与 STL 模板精选
本文总结了 C++ 算法考试中需要注意的输入输出细节、常用 STL 容器与算法函数、编程规范与模板结构等,适合临考速查与系统复习。
  目录