1-5 列表:数组实现(todo)
一、列表的基本概念
什么是基于数组的列表
列表是使用连续内存空间存储元素的线性数据结构。 列表一般采用两种方式实现, 一种是数组, 一种是链表, 本节使用数组实现。
给定一个数组arr[],根据该数组创建链表。示例:
输入: arr[] = [1, 2, 3, 4, 5]
输出: 1 -> 2 -> 3 -> 4 -> 5
说明: 给定 arr[],链表表示为
二、基于数组的列表的实现
| 编号 | 函数名 | 简短功能 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|---|
| 2.1 | 构造函数 析构函数 |
默认构造:创建空列表 带参构造:指定初始容量 析构函数:释放动态数组 |
O(1) O(n) O(1) |
O(1) O(n) O(1) |
| 2.2 | pushBack | 在列表尾部添加元素,容量不足时自动翻倍扩容 | O(1) 均摊 | O(1) |
| 2.3 | insert | 在指定位置插入元素,该位置及之后元素后移 | O(n) | O(1) |
| 2.4 | popBack | 删除尾部元素,仅减少计数不释放内存 | O(1) | O(1) |
| 2.5 | remove | 删除指定位置元素,该位置之后元素前移 | O(n) | O(1) |
| 2.6 | removeByValue | 查找并删除第一个匹配元素 | O(n) | O(1) |
| 2.7 | operator[] at front back |
下标访问(无检查) 安全访问(有检查) 访问首元素 访问尾元素 |
O(1) O(1) O(1) O(1) |
O(1) O(1) O(1) O(1) |
| 2.8 | reserve resize shrinkToFit clear |
预分配空间 调整逻辑大小 缩容至实际大小 清空列表 |
O(n) O(n) O(n) O(1) |
O(n) O(n) O(n) O(1) |
| 2.9 | find contains |
线性查找元素索引 判断是否包含元素 |
O(n) O(n) |
O(1) O(1) |
| 2.10 | 拷贝构造 拷贝赋值 移动构造 移动赋值 |
深拷贝构造 深拷贝赋值 转移资源所有权 转移资源所有权 |
O(n) O(n) O(1) O(1) |
O(n) O(n) O(1) O(1) |
| 2.11 | begin end |
返回指向首元素的指针 返回指向尾后元素的指针 |
O(1) O(1) |
O(1) O(1) |
| 2.12 | 输出列表所有元素及容量信息 | O(n) | O(1) |
2.1 构造函数与析构函数
设计要点
- 默认构造:创建空列表,容量为0
- 带形参构造:指定初始容量,预分配内存
- 析构函数:释放动态分配的数组内存
template <typename T>
class ArrayList
{
private:
T* m_data; // 存储元素的动态数组
int m_capacity; // 当前容量(总空间)
int m_currentSize; // 当前元素个数
public:
// 默认构造函数
ArrayList()
: m_data(nullptr), m_capacity(0), m_currentSize(0)
{
}
// 指定初始容量
explicit ArrayList(int initialCapacity)
: m_capacity(initialCapacity), m_currentSize(0)
{
if (initialCapacity < 0)
{
throw std::invalid_argument("Capacity cannot be negative");
}
m_data = new T[m_capacity];
}
// 析构函数
~ArrayList()
{
delete[] m_data;
}
};
2.2 尾部添加操作 (pushBack)
设计要点
- 检查容量,不足时触发扩容
- 扩容策略:容量翻倍(均摊O(1))
- 在数组末尾添加新元素
可视化演示
初始: [_, _, _, _] capacity=4, size=0
pushBack(10): [10, _, _, _] size=1
pushBack(20): [10, 20, _, _] size=2
pushBack(30): [10, 20, 30, _] size=3
pushBack(40): [10, 20, 30, 40] size=4
pushBack(50): 触发扩容
创建新数组 [_, _, _, _, _, _, _, _] capacity=8
复制数据 [10, 20, 30, 40, _, _, _, _]
添加50 [10, 20, 30, 40, 50, _, _, _] size=5
代码实现
// 在尾部添加元素
void pushBack(const T& value)
{
// 检查是否需要扩容
if (m_currentSize == m_capacity)
{
// 扩容策略:如果容量为0则设为1,否则翻倍
int newCapacity = (m_capacity == 0) ? 1 : m_capacity * 2;
resize(newCapacity);
}
m_data[m_currentSize++] = value;
}
// 扩容辅助函数
void resize(int newCapacity)
{
T* newData = new T[newCapacity];
// 复制旧数据到新数组
for (int i = 0; i < m_currentSize; i++)
{
newData[i] = m_data[i];
}
delete[] m_data;
m_data = newData;
m_capacity = newCapacity;
}
2.3 指定位置插入 (insert)
设计要点
- 检查索引合法性(0 ≤ index ≤ size)
- 容量不足时先扩容
- 将插入位置后的元素统一后移一位
可视化演示:比如在B位置插入X
初始: [A, B, C, D, _, _] size=4, capacity=6
insert(1, X):
1. 检查index=1合法
2. 检查容量充足
3. 元素后移:
i=4: [A, B, C, D, D, _] D后移
i=3: [A, B, C, C, D, _] C后移
i=2: [A, B, B, C, D, _] B后移
i=1: 停止
4. 插入X: [A, X, B, C, D, _]
5. size=5
代码实现
// 在指定位置插入元素
void insert(int index, const T& value)
{
if (index < 0 || index > m_currentSize) {
throw std::out_of_range("Insert index out of range");
}
// 检查容量
if (m_currentSize == m_capacity) {
int newCapacity = (m_capacity == 0) ? 1 : m_capacity * 2;
resize(newCapacity);
}
// 将index及之后的元素后移
for (int i = m_currentSize; i > index; i--) {
m_data[i] = m_data[i - 1];
}
m_data[index] = value;
m_currentSize++;
}
2.4 尾部删除 (popBack)
设计要点
- 检查列表非空
- 仅减少计数,不实际释放内存(由析构函数统一处理)
- 不自动缩容
可视化演示
初始: [A, B, C, D] size=4
popBack():
size减1 → [A, B, C, D] (逻辑上视为 [A, B, C])
再次popBack():
size减1 → [A, B, C, D] (逻辑上视为 [A, B])
代码实现
// 删除尾部元素
void popBack()
{
if (isEmpty())
{
throw std::runtime_error("Cannot pop from empty list");
}
m_currentSize--; // 只需减少计数
}
2.5 指定位置删除 (remove)
设计要点
- 检查索引合法性
- 将删除位置后的元素统一前移一位
- 覆盖被删除元素
可视化演示
初始: [A, B, C, D, E] size=5
remove(1): 删除B
i=1: [A, C, C, D, E] C前移覆盖B
i=2: [A, C, D, D, E] D前移
i=3: [A, C, D, E, E] E前移
size=4 → 逻辑上 [A, C, D, E]
代码实现
// 删除指定位置元素
void remove(int index)
{
checkIndex(index);
// 将index之后的元素前移
for (int i = index; i < m_currentSize - 1; i++) {
m_data[i] = m_data[i + 1];
}
m_currentSize--;
}
// 索引检查辅助函数
void checkIndex(int index) const
{
if (index < 0 || index >= m_currentSize)
{
throw std::out_of_range("Index out of range: " + std::to_string(index));
}
}
2.6 按值删除 (removeByValue)
设计要点
- 遍历查找第一个匹配元素
- 调用remove删除该元素
- 返回是否成功删除
可视化演示
初始状态: [10, 20, 30, 20, 40] m_currentSize=5
调用: removeByValue(20)
─────────────────────────────────────────────────────────
i=0: m_data[0]=10
10 == 20 ? 否 → 继续循环
列表状态: [10, 20, 30, 20, 40]
─────────────────────────────────────────────────────────
i=1: m_data[1]=20
20 == 20 ? 是 → 找到匹配
调用 remove(1)
remove(1) 执行过程:
─ 检查索引: 1 >=0 且 1 < 5 ✓
─ 元素前移:
i=1: m_data[1]=m_data[2] → [10, 30, 30, 20, 40]
i=2: m_data[2]=m_data[3] → [10, 30, 20, 20, 40]
i=3: m_data[3]=m_data[4] → [10, 30, 20, 40, 40]
─ m_currentSize-- → 4
remove(1) 返回后: [10, 30, 20, 40] size=4
return true
─────────────────────────────────────────────────────────
最终结果: [10, 30, 20, 40] m_currentSize=4
只删除了第一个匹配的20(原索引1)
第二个20(原索引3,现索引2)保留
代码实现
// 查找并删除第一个匹配元素
bool removeByValue(const T& value)
{
for (int i = 0; i < m_currentSize; i++) {
if (m_data[i] == value) {
remove(i);
return true;
}
}
return false;
}
2.7 元素访问操作
设计要点
- operator[]:快速访问,无边界检查
- at():安全访问,有边界检查
- front() / back():访问首尾元素
代码实现
// 下标访问(无边界检查)
T& operator[](int index)
{
return m_data[index];
}
const T& operator[](int index) const
{
return m_data[index];
}
// 安全访问(有边界检查)
T& at(int index)
{
checkIndex(index);
return m_data[index];
}
const T& at(int index) const
{
checkIndex(index);
return m_data[index];
}
// 访问首尾元素
T& front()
{
if (isEmpty()) {
throw std::runtime_error("List is empty");
}
return m_data[0];
}
T& back()
{
if (isEmpty()) {
throw std::runtime_error("List is empty");
}
return m_data[m_currentSize - 1];
}
2.8 容量管理操作
设计要点
- reserve:预分配空间,避免多次扩容
- resize:调整逻辑大小
- shrinkToFit:释放多余内存
代码实现
// 预分配空间
void reserve(int newCapacity)
{
if (newCapacity > m_capacity) {
resize(newCapacity);
}
}
// 调整大小
void resize(int newSize)
{
if (newSize > m_capacity) {
reserve(newSize);
}
m_currentSize = newSize;
}
// 释放多余内存
void shrinkToFit()
{
if (m_currentSize < m_capacity) {
resize(m_currentSize);
}
}
// 清空列表
void clear()
{
m_currentSize = 0;
}
// 查询接口
int size() const
{
return m_currentSize;
}
int getCapacity() const
{
return m_capacity;
}
bool isEmpty() const
{
return m_currentSize == 0;
}
2.9 查找操作
设计要点
- find:线性查找,返回索引或-1
- contains:判断是否包含某元素
代码实现
// 线性查找
int find(const T& value) const
{
for (int i = 0; i < m_currentSize; i++) {
if (m_data[i] == value) {
return i;
}
}
return -1;
}
// 判断是否包含
bool contains(const T& value) const
{
return find(value) != -1;
}
2.10 拷贝控制
设计要点
- 拷贝构造:深拷贝,复制所有元素
- 拷贝赋值:异常安全实现
- 移动构造/赋值:转移资源所有权
代码实现
// 拷贝构造函数(深拷贝)
ArrayList(const ArrayList& other)
: m_capacity(other.m_capacity), m_currentSize(other.m_currentSize)
{
m_data = new T[m_capacity];
for (int i = 0; i < m_currentSize; i++) {
m_data[i] = other.m_data[i];
}
}
// 拷贝赋值运算符
ArrayList& operator=(const ArrayList& other)
{
if (this != &other) {
T* newData = new T[other.m_capacity];
for (int i = 0; i < other.m_currentSize; i++) {
newData[i] = other.m_data[i];
}
delete[] m_data;
m_data = newData;
m_capacity = other.m_capacity;
m_currentSize = other.m_currentSize;
}
return *this;
}
// 移动构造函数
ArrayList(ArrayList&& other) noexcept
: m_data(other.m_data), m_capacity(other.m_capacity), m_currentSize(other.m_currentSize)
{
other.m_data = nullptr;
other.m_capacity = 0;
other.m_currentSize = 0;
}
// 移动赋值运算符
ArrayList& operator=(ArrayList&& other) noexcept
{
if (this != &other) {
delete[] m_data;
m_data = other.m_data;
m_capacity = other.m_capacity;
m_currentSize = other.m_currentSize;
other.m_data = nullptr;
other.m_capacity = 0;
other.m_currentSize = 0;
}
return *this;
}
2.11 迭代器支持
设计要点
- 提供begin/end指针,支持范围for循环
- 支持STL算法
代码实现
// 迭代器支持
T* begin()
{
return m_data;
}
T* end()
{
return m_data + m_currentSize;
}
const T* begin() const
{
return m_data;
}
const T* end() const
{
return m_data + m_currentSize;
}
2.12 辅助函数
// 输出列表内容
void print() const
{
std::cout << "[";
for (int i = 0; i < m_currentSize; i++) {
std::cout << m_data[i];
if (i < m_currentSize - 1) {
std::cout << ", ";
}
}
std::cout << "] (size=" << m_currentSize << ", capacity=" << m_capacity << ")\n";
}
2.x 基于数组的列表的完整实现
#include <iostream>
#include <stdexcept>
#include <algorithm>
template <typename T>
class ArrayList {
private:
T* m_data; // 存储元素的动态数组
int m_capacity; // 当前容量(总空间)
int m_currentSize; // 当前元素个数
// 扩容函数:当空间不足时调用
void resize(int newCapacity) {
// 创建新数组
T* newData = new T[newCapacity];
// 复制旧数据到新数组
for (int i = 0; i < m_currentSize; i++) {
newData[i] = m_data[i];
}
// 释放旧内存
delete[] m_data;
// 更新指针和容量
m_data = newData;
m_capacity = newCapacity;
}
// 检查索引是否合法
void checkIndex(int index) const {
if (index < 0 || index >= m_currentSize) {
throw std::out_of_range("Index out of range: " + std::to_string(index));
}
}
public:
// ==================== 构造函数与析构函数 ====================
// 默认构造函数
ArrayList()
: m_data(nullptr), m_capacity(0), m_currentSize(0)
{
}
// 指定初始容量
explicit ArrayList(int initialCapacity)
: m_capacity(initialCapacity), m_currentSize(0)
{
if (initialCapacity < 0) {
throw std::invalid_argument("Capacity cannot be negative");
}
m_data = new T[m_capacity];
}
// 析构函数
~ArrayList() {
delete[] m_data;
}
// ==================== 拷贝控制 ====================
// 拷贝构造函数(深拷贝)
ArrayList(const ArrayList& other)
: m_capacity(other.m_capacity), m_currentSize(other.m_currentSize)
{
m_data = new T[m_capacity];
for (int i = 0; i < m_currentSize; i++) {
m_data[i] = other.m_data[i];
}
}
// 拷贝赋值运算符
ArrayList& operator=(const ArrayList& other) {
if (this != &other) { // 防止自赋值
// 复制并交换(异常安全)
T* newData = new T[other.m_capacity];
for (int i = 0; i < other.m_currentSize; i++) {
newData[i] = other.m_data[i];
}
delete[] m_data;
m_data = newData;
m_capacity = other.m_capacity;
m_currentSize = other.m_currentSize;
}
return *this;
}
// 移动构造函数(C++11)
ArrayList(ArrayList&& other) noexcept
: m_data(other.m_data), m_capacity(other.m_capacity), m_currentSize(other.m_currentSize)
{
other.m_data = nullptr;
other.m_capacity = 0;
other.m_currentSize = 0;
}
// 移动赋值运算符
ArrayList& operator=(ArrayList&& other) noexcept {
if (this != &other) {
delete[] m_data;
m_data = other.m_data;
m_capacity = other.m_capacity;
m_currentSize = other.m_currentSize;
other.m_data = nullptr;
other.m_capacity = 0;
other.m_currentSize = 0;
}
return *this;
}
// ==================== 基本操作 ====================
// 在尾部添加元素
void pushBack(const T& value) {
// 检查是否需要扩容
if (m_currentSize == m_capacity) {
// 扩容策略:如果容量为0则设为1,否则翻倍
int newCapacity = (m_capacity == 0) ? 1 : m_capacity * 2;
resize(newCapacity);
}
m_data[m_currentSize++] = value;
}
// 在指定位置插入元素
void insert(int index, const T& value) {
if (index < 0 || index > m_currentSize) {
throw std::out_of_range("Insert index out of range");
}
// 检查容量
if (m_currentSize == m_capacity) {
int newCapacity = (m_capacity == 0) ? 1 : m_capacity * 2;
resize(newCapacity);
}
// 将index及之后的元素后移
for (int i = m_currentSize; i > index; i--) {
m_data[i] = m_data[i - 1];
}
m_data[index] = value;
m_currentSize++;
}
// 删除尾部元素
void popBack() {
if (isEmpty()) {
throw std::runtime_error("Cannot pop from empty list");
}
m_currentSize--; // 只需减少计数,不实际删除(析构时统一处理)
}
// 删除指定位置元素
void remove(int index) {
checkIndex(index);
// 将index之后的元素前移
for (int i = index; i < m_currentSize - 1; i++) {
m_data[i] = m_data[i + 1];
}
m_currentSize--;
}
// 查找并删除第一个匹配元素
bool removeByValue(const T& value) {
for (int i = 0; i < m_currentSize; i++) {
if (m_data[i] == value) {
remove(i);
return true;
}
}
return false;
}
// ==================== 访问元素 ====================
// 下标访问(无边界检查)
T& operator[](int index) {
return m_data[index];
}
const T& operator[](int index) const {
return m_data[index];
}
// 安全访问(有边界检查)
T& at(int index) {
checkIndex(index);
return m_data[index];
}
const T& at(int index) const {
checkIndex(index);
return m_data[index];
}
// 访问首尾元素
T& front() {
if (isEmpty()) {
throw std::runtime_error("List is empty");
}
return m_data[0];
}
T& back() {
if (isEmpty()) {
throw std::runtime_error("List is empty");
}
return m_data[m_currentSize - 1];
}
// ==================== 容量与大小 ====================
int size() const
{
return m_currentSize;
}
int getCapacity() const
{
return m_capacity;
}
bool isEmpty() const
{
return m_currentSize == 0;
}
// 预分配空间(优化多次插入性能)
void reserve(int newCapacity) {
if (newCapacity > m_capacity) {
resize(newCapacity);
}
}
// 调整大小(新增元素默认初始化)
void resize(int newSize) {
if (newSize > m_capacity) {
reserve(newSize);
}
// 如果扩大,新元素已默认构造
// 如果缩小,只需调整计数
m_currentSize = newSize;
}
// 清空列表(不释放内存)
void clear() {
m_currentSize = 0;
}
// 释放多余内存(缩容至实际大小)
void shrinkToFit() {
if (m_currentSize < m_capacity) {
resize(m_currentSize);
}
}
// ==================== 查找与算法 ====================
// 线性查找
int find(const T& value) const {
for (int i = 0; i < m_currentSize; i++) {
if (m_data[i] == value) {
return i;
}
}
return -1; // 未找到
}
// 判断是否包含
bool contains(const T& value) const {
return find(value) != -1;
}
// ==================== 迭代器支持 ====================
T* begin()
{
return m_data;
}
T* end()
{
return m_data + m_currentSize;
}
const T* begin() const
{
return m_data;
}
const T* end() const
{
return m_data + m_currentSize;
}
// ==================== 输出 ====================
void print() const {
std::cout << "[";
for (int i = 0; i < m_currentSize; i++) {
std::cout << m_data[i];
if (i < m_currentSize - 1) {
std::cout << ", ";
}
}
std::cout << "] (size=" << m_currentSize << ", capacity=" << m_capacity << ")\n";
}
};
三、完整功能测试
| 测试函数 | 覆盖功能点 | 对应章节 |
|---|---|---|
testBasicOperations |
构造、pushBack、insert、at、front、back、operator[] | 2.1, 2.2, 2.3, 2.7 |
testDeleteOperations |
remove、popBack、removeByValue、clear | 2.4, 2.5, 2.6, 2.8 |
testFindOperations |
find、contains | 2.9 |
testCapacityManagement |
reserve、resize、shrinkToFit、getCapacity | 2.8 |
testIterator |
begin、end、范围for循环 | 2.11 |
testCopyControl |
拷贝构造、拷贝赋值、移动构造、移动赋值 | 2.10 |
testExceptions |
所有异常抛出场景 | 全章节 |
testEdgeCases |
边界条件、大量数据、连续扩容 | 全章节 |
3.1 基本操作测试
void testBasicOperations()
{
std::cout << "=== 基本操作测试 ===\n";
ArrayList<int> list;
// 测试空列表状态
assert(list.isEmpty());
assert(list.size() == 0);
std::cout << "Empty list created: size=" << list.size()
<< ", isEmpty=" << list.isEmpty() << "\n";
// 测试pushBack和自动扩容
list.pushBack(10);
list.pushBack(20);
list.pushBack(30);
list.print();
assert(list.size() == 3);
assert(list[0] == 10);
assert(list[1] == 20);
assert(list[2] == 30);
std::cout << "After 3 pushBack: size=" << list.size()
<< ", capacity=" << list.getCapacity() << "\n";
// 测试insert
list.insert(1, 15);
list.print();
assert(list.size() == 4);
assert(list[1] == 15);
std::cout << "After insert(1, 15): size=" << list.size() << "\n";
// 测试访问操作
std::cout << "Element at index 2: " << list.at(2) << "\n";
std::cout << "Front: " << list.front() << ", Back: " << list.back() << "\n";
assert(list.at(2) == 20);
assert(list.front() == 10);
assert(list.back() == 30);
std::cout << "Basic operations test passed!\n\n";
}
3.2 删除操作测试
void testDeleteOperations()
{
std::cout << "=== 删除操作测试 ===\n";
ArrayList<int> list;
// 准备数据
for (int i = 10; i <= 50; i += 10) {
list.pushBack(i);
}
list.print(); // [10, 20, 30, 40, 50]
assert(list.size() == 5);
// 测试remove(删除中间元素)
list.remove(1); // 删除20
list.print(); // [10, 30, 40, 50]
assert(list.size() == 4);
assert(list[1] == 30);
std::cout << "After remove(1): size=" << list.size() << "\n";
// 测试popBack
list.popBack(); // 删除50
list.print(); // [10, 30, 40]
assert(list.size() == 3);
assert(list.back() == 40);
std::cout << "After popBack: size=" << list.size()
<< ", back=" << list.back() << "\n";
// 测试removeByValue
bool found = list.removeByValue(30); // 删除30
assert(found);
list.print(); // [10, 40]
assert(list.size() == 2);
assert(list[0] == 10);
assert(list[1] == 40);
std::cout << "After removeByValue(30): size=" << list.size() << "\n";
// 测试删除不存在的值
bool notFound = list.removeByValue(999);
assert(!notFound);
std::cout << "removeByValue(999) returned false as expected\n";
// 测试清空
list.clear();
assert(list.isEmpty());
assert(list.size() == 0);
std::cout << "After clear: size=" << list.size()
<< ", isEmpty=" << list.isEmpty() << "\n";
std::cout << "Delete operations test passed!\n\n";
}
3.3 查找操作测试
void testFindOperations()
{
std::cout << "=== 查找操作测试 ===\n";
ArrayList<int> list;
list.pushBack(10);
list.pushBack(20);
list.pushBack(30);
list.pushBack(40);
list.print();
// 测试find
int idx = list.find(30);
std::cout << "Found 30 at index: " << idx << "\n";
assert(idx == 2);
int notFound = list.find(999);
std::cout << "Find 999 returned: " << notFound << "\n";
assert(notFound == -1);
// 测试contains
assert(list.contains(20));
assert(!list.contains(999));
std::cout << "Contains 20: " << list.contains(20) << "\n";
std::cout << "Contains 999: " << list.contains(999) << "\n";
std::cout << "Find operations test passed!\n\n";
}
3.4 容量管理测试
void testCapacityManagement()
{
std::cout << "=== 容量管理测试 ===\n";
// 测试reserve
ArrayList<double> dlist;
std::cout << "Initial capacity: " << dlist.getCapacity() << "\n";
dlist.reserve(100);
std::cout << "Capacity after reserve(100): " << dlist.getCapacity() << "\n";
assert(dlist.getCapacity() >= 100);
assert(dlist.isEmpty()); // reserve不改变size
// 测试添加元素
for (int i = 0; i < 10; i++) {
dlist.pushBack(i * 1.5);
}
dlist.print();
assert(dlist.size() == 10);
std::cout << "After adding 10 elements: size=" << dlist.size()
<< ", capacity=" << dlist.getCapacity() << "\n";
// 测试shrinkToFit
dlist.shrinkToFit();
std::cout << "After shrinkToFit: capacity=" << dlist.getCapacity() << "\n";
assert(dlist.getCapacity() == dlist.size());
// 测试resize
ArrayList<int> ilist;
ilist.resize(20);
std::cout << "After resize(20): size=" << ilist.size()
<< ", capacity=" << ilist.getCapacity() << "\n";
assert(ilist.size() == 20);
// 缩小resize
for (int i = 0; i < 20; i++) {
ilist.pushBack(i);
}
ilist.resize(5); // 缩小到5
std::cout << "After resize to 5: size=" << ilist.size() << "\n";
assert(ilist.size() == 5);
std::cout << "Capacity management test passed!\n\n";
}
3.5 迭代器与遍历测试
void testIterator()
{
std::cout << "=== 迭代器测试 ===\n";
ArrayList<int> list;
for (int i = 1; i <= 5; i++) {
list.pushBack(i * 10);
}
// 测试范围for循环
std::cout << "Range-based for: ";
for (const auto& elem : list) {
std::cout << elem << " ";
}
std::cout << "\n";
// 测试begin/end
std::cout << "Using begin/end: ";
for (auto it = list.begin(); it != list.end(); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
// 测试修改迭代器指向的元素
*list.begin() = 999;
assert(list.front() == 999);
std::cout << "After modify via iterator: ";
list.print();
std::cout << "Iterator test passed!\n\n";
}
3.6 拷贝控制测试
void testCopyControl()
{
std::cout << "=== 拷贝控制测试 ===\n";
ArrayList<int> original;
for (int i = 1; i <= 5; i++) {
original.pushBack(i);
}
original.print();
// 测试拷贝构造
ArrayList<int> copy1 = original;
copy1.print();
assert(copy1.size() == original.size());
assert(copy1[0] == original[0]);
copy1[0] = 999; // 修改拷贝不影响原列表
assert(original[0] != 999);
std::cout << "Copy constructor: original[0]=" << original[0]
<< ", copy[0]=" << copy1[0] << "\n";
// 测试拷贝赋值
ArrayList<int> copy2;
copy2 = original;
assert(copy2.size() == original.size());
copy2.print();
std::cout << "Copy assignment test passed\n";
// 测试移动构造
ArrayList<int> temp = original;
ArrayList<int> moved1 = std::move(temp);
moved1.print();
assert(moved1.size() == 5);
// temp现在处于有效但未指定状态
std::cout << "Move constructor test passed\n";
// 测试移动赋值
ArrayList<int> moved2;
moved2 = std::move(moved1);
moved2.print();
assert(moved2.size() == 5);
std::cout << "Move assignment test passed\n";
std::cout << "Copy control test passed!\n\n";
}
3.7 异常安全测试
void testExceptions()
{
std::cout << "=== 异常安全测试 ===\n";
ArrayList<int> list;
// 测试空列表访问异常
try {
list.front();
assert(false); // 不应执行到这里
} catch (const std::runtime_error& e) {
std::cout << "front() on empty list caught: " << e.what() << "\n";
}
try {
list.back();
assert(false);
} catch (const std::runtime_error& e) {
std::cout << "back() on empty list caught: " << e.what() << "\n";
}
try {
list.popBack();
assert(false);
} catch (const std::runtime_error& e) {
std::cout << "popBack() on empty list caught: " << e.what() << "\n";
}
// 测试越界访问异常
list.pushBack(10);
try {
list.at(999);
assert(false);
} catch (const std::out_of_range& e) {
std::cout << "at(999) caught: " << e.what() << "\n";
}
// 测试非法插入位置
try {
list.insert(5, 100); // size=1, 只能插入到0或1
assert(false);
} catch (const std::out_of_range& e) {
std::cout << "insert(5) out of range caught\n";
}
// 测试非法删除位置
try {
list.remove(5);
assert(false);
} catch (const std::out_of_range& e) {
std::cout << "remove(5) out of range caught\n";
}
// 测试负容量构造
try {
ArrayList<int> badList(-10);
assert(false);
} catch (const std::invalid_argument& e) {
std::cout << "Negative capacity caught: " << e.what() << "\n";
}
std::cout << "Exception safety test passed!\n\n";
}
3.8 边界条件测试
void testEdgeCases()
{
std::cout << "=== 边界条件测试 ===\n";
// 测试单元素列表
ArrayList<int> single;
single.pushBack(42);
assert(single.front() == single.back());
single.remove(0);
assert(single.isEmpty());
std::cout << "Single element list test passed\n";
// 测试在头部和尾部插入
ArrayList<int> list;
list.pushBack(20); // [20]
list.insert(0, 10); // [10, 20] 头部插入
list.insert(2, 30); // [10, 20, 30] 尾部插入
list.print();
assert(list.size() == 3);
std::cout << "Head/tail insert test passed\n";
// 测试删除头部和尾部
list.remove(0); // 删除头部 [20, 30]
list.remove(1); // 删除尾部 [20]
list.print();
assert(list.size() == 1);
assert(list[0] == 20);
std::cout << "Head/tail remove test passed\n";
// 测试大量数据
ArrayList<int> large;
for (int i = 0; i < 10000; i++) {
large.pushBack(i);
}
assert(large.size() == 10000);
assert(large.front() == 0);
assert(large.back() == 9999);
std::cout << "Large data test (10000 elements) passed\n";
// 测试连续扩容
ArrayList<int> growing;
int prevCapacity = 0;
for (int i = 0; i < 100; i++) {
growing.pushBack(i);
if (growing.getCapacity() != prevCapacity) {
std::cout << "Expanded at size=" << i
<< ", new capacity=" << growing.getCapacity() << "\n";
prevCapacity = growing.getCapacity();
}
}
std::cout << "Continuous expansion test passed\n";
std::cout << "Edge cases test passed!\n\n";
}
3.9 主函数入口
int main()
{
std::cout << "========================================\n";
std::cout << " ArrayList Comprehensive Test Suite \n";
std::cout << "========================================\n\n";
testBasicOperations();
testDeleteOperations();
testFindOperations();
testCapacityManagement();
testIterator();
testCopyControl();
testExceptions();
testEdgeCases();
std::cout << "========================================\n";
std::cout << " All tests passed successfully! \n";
std::cout << "========================================\n";
return 0;
}


浙公网安备 33010602011771号