List容器(上)实战探索解析
前言:链表作为基础数据结构,凭借非连续存储特性在频繁插入/删除时具有O(1)优势,但牺牲了随机访问性能。本文将剖析std::list的内存模型和迭代器机制,对比其他STL容器性能,并通过代码示例演示其适用场景与优化策略,帮助开发者掌握这一经典结构的现代C++实现精髓。
目录
List的介绍
List实例化
尾插元素
访问元素
指定位置前插入
指定位置删除
排序
(升序)
(降序)
拼接
去重
反转
List的介绍
List也是C++标准模板库(STL)中的一种容器,它的内存存储特点与string、vector不同,它的存储不是连续的,List将元素存储在不连续的内存中,通过指针连接前一个节点和后一个节点。综合来说:就是另一种vector:只是内存存储变成了不连续。
List实例化
list<类型> 就是它的数据类型,后面跟上变量名即可,例如:
//list实例化
list<int> V{ 1,2,3,4,5 };
尾插元素
使用和之前的两个容器string与vector一样,如下:
//list实例化
list<int> V;
//尾插元素
V.push_back(1);
V.push_back(2);
V.push_back(3);
访问元素
在C++中支持迭代器的容器那就支持auto,而不支持迭代器的容器很少:
stack queue priority_queue
所以我们可以通过迭代器去访问元素,例如:
//迭代器读\写
auto it = V.begin();
while (it != V.end())
{cout << *it << " ";it++;
}
cout << endl;
//auto的底层就是迭代器
for (auto e : V)
{cout << e << " ";
}
cout << endl;
指定位置前插入
//指定位置前插入
V.insert(V.begin(), 5);
指定位置删除
//指定位置删除
V.erase(V.begin());
注意:使用erase之后,如果不接收返回值,那么迭代器就会失效。
排序
(升序)
List的排序属于稳定排序(n logn)
v.sort();
(降序)
V.sort(greater<int>());
拼接
拼接支持:整体拼接、单个元素拼接、范围拼接,具体的我们实战的时候再去了解
拼接我们在合成多个链表时可以使用,比如:先拼接多个链表再用排序,这样就实现了整体有序
整体拼接:
//拼接V2在V1的末尾
V1.splice(V1.end(), V2);
去重
去重的前提是元素已经有序
V2.unique();
反转
V2.reverse();
注意:
pos找到的是5的位置,而reverse翻转的是“闭区间,开区间”的元素,也就是0~4。左闭右开。
虽然对于 list 属于非连续的存储,我们还是可以使用 ++ ,这是因为支持了运算符重载,++ 的本质是 ->next,比如我们获取 pos 位置的下一个地址应该用 ++ 而不是 +1