C++list列表
我想把三个常用的序列式放在一起对比一下是有必要的:
vector : vector和built-in数组类似,拥有一段连续的内存空间,能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当插入较多的元素后,预留内存空间可能不够,需要重新申请一块足够大的内存并把原来的数据拷贝到新的内存空间。这些影响了vector的效率,但是实际上用的最多的还是vector容器,建议大多数时候使用vector效率一般是不错的
list: list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。
deque: deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。
因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,具体可以遵循下面的原则:
1. 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2. 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3. 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
#include<iostream> #include <list> int main() { std::list<int> l1; //声明一个空列表 std::list<int> l2(5); //声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的 std::list<int> l3(3, 0); //创建含有3个元素的list,值都是0 std::list<int> l4(l2); //使用l2初始化l4 std::list<int> l5(l2.begin(), l2.end()); //同l4 return 0; }
#include<iostream> #include <list> int main() { std::list<int> L; for (int i = 0; i < 5; ++i) { L.push_back(i+10); //在list的末尾添加一个元素 } std::list<int>::iterator iter; //创建迭代器 int x=L.front(); //返回第一个元素 std::cout << x << std::endl; x = L.back(); //返回最后一个元素 std::cout << x << std::endl; bool b = L.empty(); //判断是否为空 //如果空 返回真 std::cout << b << std::endl; L.insert(L.begin(), 100); //在L的开始位置插入100 L.insert(L.begin(),2, 200); //在L的开始位置插入2个200 //l1.insert(l1.begin(), l2.begin(), l2.end()); 在l1的开始位置插入l2的从开始到结束的所有位置的元素 L.erase(L.begin()); //将L的第一个元素删除 //L.erase(L.begin(), L.end()); //将L的从begin()到end()之间的元素删除 //L.clear(); // 清空list中的所有元素 L.push_front(1000);//在L的头部位置插入数据 L.pop_front(); // 删除第一个元素,序列必须不为空 L.pop_back(); // 删除最后一个元素,序列必须不为空 L.reverse(); //倒序 for (iter = L.begin(); iter != L.end(); iter++) /* L.begin()返回第一个元素的迭代器 L.end() 返回最后一个元素的下一位置的迭代器 */ { std::cout << *iter << " "; // *iter 返回指定迭代器的数据 } std::cout << std::endl; //l1.assign(n, val)将 l1中元素变为n个T(val) //l1.assign(l2.begin(),l2.end())将l2中的从l2.begin()到l2.end()之间的数值赋值给l1 //swap():交换两个表(两个重载),一个是l1.swap(l2); 另外一个是swap(l1,l2),都可能完成连个链表的交换 //l1.merge(l2,greater<int>()); 合并两个表,调用结束后l2变为空,l1中元素包含原来l1 和 l2中的元素,并且排好序,升序,其实默认是升序,greater<int>()可以省略 return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2019-08-28 qt5-信号和槽