深入C++编程:第7章 列表(list)的实现与使用(无习题)
在C++中,std::list
是一个双向链表的实现,属于标准模板库(STL)的一部分。与std::vector
相比,std::list
在某些操作上具有不同的性能特性,例如插入或者删除操作不涉及大量元素的移动,因此在特定用例中可能更为高效。
实现概述
std::list
是通过双向链表实现的。每个节点包含一个数据元素及指向前后两个节点的指针。这种结构允许在常数时间内进行插入或删除操作(给定指向操作位置的迭代器)。
使用方法
以下是一些常用的std::list
操作:
初始化
#include <iostream>
#include <list>
int main() {
std::list<int> mylist; // 创建一个空的整数列表
std::list<int> mylist2(5, 10); // 创建一个包含5个元素,全都初始化为10的列表
return 0;
}
插入和删除元素
#include <iostream>
#include <list>
int main() {
std::list<int> mylist = {1, 2, 3, 4};
// 在末尾插入元素
mylist.push_back(5);
// 在开头插入元素
mylist.push_front(0);
// 删除末尾元素
mylist.pop_back();
// 删除开头元素
mylist.pop_front();
// 通过迭代器插入元素
auto it = mylist.begin();
std::advance(it, 2); // 移动迭代器到第三个位置
mylist.insert(it, 99);
return 0;
}
迭代和访问元素
#include <iostream>
#include <list>
int main() {
std::list<int> mylist = {1, 2, 3, 4, 5};
// 使用迭代器遍历
for (auto it = mylist.begin(); it != mylist.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 直接访问元素
mylist.front() = 10; // 修改第一个元素
mylist.back() = 20; // 修改最后一个元素
return 0;
}
其他常用操作
#include <iostream>
#include <list>
int main() {
std::list<int> mylist = {10, 20, 30, 40, 50};
// 获取大小
std::cout << "Size: " << mylist.size() << std::endl;
// 检查是否为空
if (mylist.empty()) {
std::cout << "List is empty." << std::endl;
} else {
std::cout << "List is not empty." << std::endl;
}
// 清空列表
mylist.clear();
return 0;
}
性能注意事项
插入和删除:在双向链表中,这些操作通常为O(1),与
std::vector
相比,不需要移动其他元素。然而,随机访问一个元素则需要O(n)时间,因为必须遍历链表。内存使用:由于每个元素需要两个额外的指针(前后指针),因此链表的内存开销比数组高。
总结来说,std::list
在需要频繁进行插入或删除操作的场景下是非常有用的选择,但就一般的高效数据访问而言,std::vector
可能是更好的选择。要根据具体使用场景选择合适的数据结构。