C++容器list
- 定义
- 构造函数
- 1、默认构造函数
- 2、指定大小构造函数
- 3、指定大小与初始值构造函数
- 4、拷贝构造函数
- 5、移动构造函数
- 6、范围构造函数
- 7、指定初始化列表构造函数
- 元素访问
- 容量大小
- 迭代器
- 修改操作
- 链表操作
- 其他
定义
std::list - cppreference.cn - C++参考手册
- 双向链表:每个元素(节点)包含数据、一个指向前一个节点的指针和一个指向后一个节点的指针
- 非连续存储:元素在内存中不是连续存放的,而是通过指针链接
- 高效修改:插入和删除操作(包括中间位置)的时间复杂度为 O(1),前提是已知插入/删除位置的迭代器
- 不支持随机访问:不能通过下标
[] 直接访问第 n 个元素,必须从头或尾遍历,时间复杂度为 O(n) - 稳定迭代器:只要不删除元素,插入操作不会使其他元素的迭代器、指针或引用失效。这是
list 相对于 vector 和 deque 的巨大优势
构造函数
1、默认构造函数
创建空的list,长度为0
int main()
{system("chcp 65001");list<std::u8string> list1;cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;
}
2、指定大小构造函数
std::string getStringFromU8string(const std::u8string& u8str) {return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}std::u8string getU8stingFromString(const std::string& str) {return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}int main()
{system("chcp 65001");list<std::u8string> list1(4);cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}
}
3、指定大小与初始值构造函数
int main()
{system("chcp 65001");list<std::u8string> list1(4, u8"&&");cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}
}
4、拷贝构造函数
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list<std::u8string> list2(list1);cout << "list2.size()= " << list2.size() << endl;cout << "list2.max_size()= " << list2.max_size() << endl;for (auto it : list2){cout << "list2-> " << getStringFromU8string(it) << endl;}
}
5、移动构造函数
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list<std::u8string> list2(std::move(list1));cout << "list2.size()= " << list2.size() << endl;cout << "list2.max_size()= " << list2.max_size() << endl;for (auto it : list2){cout << "list2-> " << getStringFromU8string(it) << endl;}cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;
}
6、范围构造函数
int main()
{system("chcp 65001");std::array<std::u8string, 4> arr1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list<std::u8string> list1(arr1.rbegin(), arr1.rend());cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}
}
7、指定初始化列表构造函数
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list<std::u8string> list2{ u8"张三", u8"李四" };cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}
}
元素访问
不支持下标访问
| 函数 | 描述 |
|---|
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;cout << "list1.front()= " << getStringFromU8string(list1.front()) << endl;cout << "list1.back()= " << getStringFromU8string(list1.back()) << endl;
}
容量大小
| 函数 | 描述 |
|---|
empty() | 如果 list 为空,返回 true。 |
size() | 返回当前元素数量。 |
max_size() | 返回容器可容纳的最大元素数量。 |
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };cout << "list1.empty()= " << boolalpha << list1.empty() << endl;cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;cout << "list1.front()= " << getStringFromU8string(list1.front()) << endl;cout << "list1.back()= " << getStringFromU8string(list1.back()) << endl;
}
迭代器
begin-end与rbegin-rend
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}for (auto it = list1.begin(); it != list1.end(); it++){cout << "begin-end list1-> " << getStringFromU8string(*it) << endl;}for (auto it = list1.cbegin(); it != list1.cend(); it++){cout << "cbegin-cend list1-> " << getStringFromU8string(*it) << endl;}for (auto it = list1.rbegin(); it != list1.rend(); it++){cout << "rbegin-rend list1-> " << getStringFromU8string(*it) << endl;}
}
修改操作
| 函数 | 描述 |
|---|
push_back(value) | 在末尾插入一个元素 |
push_front(value) | 在开头插入一个元素。 |
pop_back() | 删除最后一个元素。 |
pop_front() | 删除第一个元素。 |
emplace_back(args...) | 在末尾就地构造一个元素(不用复制) |
emplace_front(args...) | 在开头就地构造一个元素(不用复制) |
emplace(pos, args...) | 在位置 pos 就地构造一个元素(不用复制) |
insert(pos, value) | 在位置 pos 插入一个元素。 |
insert(pos, n, value) | 在位置 pos 插入 n 个 value。 |
insert(pos, first, last) | 在位置 pos 插入范围 [first, last) 的元素。 |
erase(pos) | 删除位置 pos 的元素,返回下一个元素的迭代器。 |
erase(first, last) | 删除范围 [first, last) 的元素,返回 last 迭代器。 |
clear() | 删除所有元素。 |
resize(n) | 调整大小到 n。如果变大,新元素用默认值初始化(小于实际元素个数,会删除后面的元素) |
swap(other) | 与另一个 list 交换内容。 |
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list1.push_front(u8"哈尔滨");list1.emplace_front(u8"长春");list1.push_back(u8"沈阳");list1.emplace_back(u8"葫芦岛");for (auto it : list1){cout << "list1-> " << getStringFromU8string(it) << endl;}list1.pop_front();list1.pop_back();list1.erase(list1.begin());list1.erase(std::next(list1.begin(), 2));list1.erase(list1.begin(), list1.end());for (auto it : list1){cout << "after delete, list1-> " << getStringFromU8string(it) << endl;}list1.insert(list1.begin(), u8"测试1");list1.insert(std::next(list1.begin(), 1), u8"测试2");list1.insert(std::next(list1.begin(), 2), 2, u8"&&");std::array<std::u8string, 2> arr1 = { u8"张三",u8"李四" };list1.insert(list1.begin(), arr1.begin(), arr1.end());for (auto it : list1){cout << "after insert, list1-> " << getStringFromU8string(it) << endl;}list1.resize(2);cout << "list1.size()= " << list1.size() << endl;cout << "list1.max_size()= " << list1.max_size() << endl;for (auto it : list1){cout << "after resize, list1-> " << getStringFromU8string(it) << endl;}list1.clear();
}
链表操作
| 函数 | 描述 |
|---|
splice(pos, other, it) | 将 other 中 it 指向的元素移动到 l 的 pos 位置。O(1) |
splice(pos, other, first, last) | 将 other 中 [first, last) 范围的元素移动到 l 的 pos 位置。O(1) |
remove(value) | 删除所有值为 value 的元素。 |
remove_if(pred) | 删除所有满足谓词 pred 的元素。 |
unique() | 删除连续的重复元素(只保留一个)。 |
unique(pred) | 使用自定义比较函数删除连续的重复元素。 |
sort() | 对元素进行排序(默认升序)。 |
sort(comp) | 使用自定义比较函数排序。 |
reverse() | 反转 list 中元素的顺序。 |
merge(other) | 将已排序的 other 合并到 l 中,并保持有序。other 变为空。 |
int main()
{system("chcp 65001");list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };list<std::u8string> list2 = { u8"张三",u8"李四" };list1.splice(list1.begin(), list2, list2.begin());for (auto it : list1){cout << "afet splice, list1-> " << getStringFromU8string(it) << endl;}list1.remove(u8"张三");list1.sort();for (auto it : list1){cout << "afet sort, list1-> " << getStringFromU8string(it) << endl;}list1.reverse();for (auto it : list1){cout << "afet reverse, list1-> " << getStringFromU8string(it) << endl;}list1.sort();list2.sort();list1.merge(list2);cout << "afet merge, list1.size()= " << list1.size() << endl;cout << "afet merge, list2.size()= " << list2.size() << endl;
}
其他
| 特性 | std::list | std::vector | std::deque |
|---|
| 任意位置插入/删除 | O(1) (已知位置) | O(n) | O(n) (中间) / O(1) (首尾) |
| 头部插入/删除 | O(1) | O(n) | O(1) |
| 尾部插入/删除 | O(1) | O(1) 均摊 | O(1) |
| 随机访问 | 不支持 | O(1) | O(1) |
| 内存布局 | 非连续 (链表) | 连续 | 分段连续 |
| 迭代器失效 | 仅被删除元素的迭代器失效 | 插入/删除可能导致大量失效 | 插入/删除可能导致大量失效 |
splice 操作 | O(1) | 不支持 | 不支持 |
| 内存开销 | 高 (每个元素有额外的指针开销) | 低 | 中等 |
| 缓存局部性 | 差 | 好 | 中等 |