一、序列式容器

1. vector

vector容器详解

2. deque

deque容器是双端队列,支持快速随机访问,在头尾位置插入/删除元素速度很快。

  • vector容器对于在头部的插入、删除效率低,且数据量越大,效率越低。相对而言,deque容器对于在头部的插入、删除速度比vector容器快
  • vector容器访问元素的速度比deque容器快
  • deque容器的内存重分配优于vector容器,因为其内部结构不需要复制所有元素

deque容器内部有一个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据。中控器维护的是每个缓冲区的地址,使得使用deque容器时像是一片连续的内存空间。

3. list

STL中的list容器是一个双向循环链表,只支持双向顺序访问,在list容器中任何位置插入/删除速度很快。

  • 链表中的迭代器只支持前移和后移
  • 插入/删除操作不会造成原有的迭代器失效

所有不支持随机访问迭代器的容器, 不可以用标准算法, 但内部会提供对应一些算法!

#include <iostream>
#include <list>
using namespace std;void printList(const list<int>& L)
{for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {cout << *it << " ";}cout << endl;
}int main()
{list<int> L;L.push_back(90);L.push_back(30);L.push_back(20);L.push_back(70);printList(L);    // 90 30 20 70// 反转L.reverse();printList(L);    // 70 20 30 90// 排序,默认升序L.sort();printList(L);   // 20 30 70 90// 排序,降序排序L.sort([](const int& num1, const int& num2) {return num1 > num2; });printList(L); // 90 70 30 20system("pause");return 0;
}

什么情况下用vector,什么情况下用list,什么情况下用deque?

  • vector支持快速随机访问,但在非尾部插入/删除数据时效率很低,适合对象简单,对象数量变化不大,随机访问频繁的情况
  • 需要从首尾两端进行插入/删除操作的时候可以选择deque
  • 除非必要,我们尽可能选择使用vector而非deque,因为deque的迭代器比vector迭代器复杂很多
  • list不支持随机访问,适用于对象大,对象数量变化频繁,插入和删除频繁的情况。

二、配接器

1. stack

栈是一种先进后出的数据结构,栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。

#include <iostream>
#include <stack>
using namespace std;int main()
{stack<int> s;// 入栈s.push(10);s.push(20);s.push(30);// 栈是否为空while (!s.empty()){// 返回栈顶元素cout << "栈顶元素为: " << s.top() << endl;// 出栈s.pop();}// 返回栈的大小cout << "栈的大小为:" << s.size() << endl;system("pause");return 0;
}

2. queue

队列是一种先进先出的数据结构,队列允许从一端新增元素,从另一端移除元素,队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为。

#include <iostream>
#include <queue>
#include <string>
using namespace std;class Person
{friend ostream& operator<<(ostream& out, const Person& p);
public:Person(string name, int age) {this->m_Name = name;this->m_Age = age;}
private:string m_Name;int m_Age;
};ostream& operator<<(ostream& out, const Person& p)
{out << "姓名:" << p.m_Name << " 年龄:" << p.m_Age;return out;
}int main()
{queue<Person> q;Person p1("唐僧", 30);Person p2("孙悟空", 1000);Person p3("猪八戒", 900);Person p4("沙僧", 800);// 入队q.push(p1);q.push(p2);q.push(p3);q.push(p4);// 队列是否为空while (!q.empty()){// 返回队头元素cout << q.front() << endl;// 返回队尾元素cout << q.back() << endl;// 出队q.pop();}// 返回队列大小cout << "队列大小为: " << q.size() << endl;system("pause");return 0;
}

三、关联式容器

1. set / multiset

  • set/multiset属于关联式容器,底层结构是用红黑树实现
  • 所有元素在插入时自动按升序排序
  • set不允许容器中有重复的元素,multiset允许容器中有重复的元素
  • 对于自定义数据类型,set容器必须指定排序规则
// 基本使用
#include <iostream>
#include <set>
using namespace std;void printSet(set<int>& s)
{for (set<int>::iterator it = s.begin(); it != s.end(); it++){cout << *it << " ";}cout << endl;
}int main()
{set<int> s;// 插入s.insert(10);s.insert(30);s.insert(20);s.insert(40);s.insert(50);s.insert(60);// 容器是否为空if (s.empty()) {cout << "set为空" << endl;}else {// 返回容器中元素的数目cout << "set的大小为: " << s.size() << endl; // 6}// 删除s.erase(s.begin());printSet(s);   // 20 30 40 50 60s.erase(60);printSet(s);   // 20 30 40 50// 查找set<int>::iterator pos = s.find(30);// 统计// 对于set容器来说,结果为0或1int num = s.count(30);cout << "num = " << num << endl;   // 1system("pause");return 0;
}
// set不允许容器中有重复的元素,multiset允许容器中有重复的元素
#include <iostream>
#include <set>
using namespace std;int main()
{// set不允许插入重复值// set插入数据的同时会返回插入结果set<int> s;pair<set<int>::iterator, bool> ret = s.insert(10);if (ret.second) {cout << "第一次插入成功!" << endl;   // √}else {cout << "第一次插入失败!" << endl;}ret = s.insert(10);if (ret.second) {cout << "第二次插入成功!" << endl;}else {cout << "第二次插入失败!" << endl; // √}// multiset允许插入重复的值multiset<int> ms;ms.insert(10);ms.insert(10);for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) {cout << *it << " ";     // 10 10}cout << endl;system("pause");return 0;
}
// 所有元素在插入时自动按升序排序
#include <iostream>
#include <set>
using namespace std;class MyCompare
{public:bool operator()(int v1, int v2) const {return v1 > v2;}
};int main()
{set<int> s1;s1.insert(10);s1.insert(40);s1.insert(20);s1.insert(30);s1.insert(50);// set容器默认升序排序for (auto v : s1)cout << v << " ";cout << endl;  // 10 20 30 40 50// 指定降序排序set<int, MyCompare> s2;s2.insert(10);s2.insert(40);s2.insert(20);s2.insert(30);s2.insert(50);for (auto v : s1)cout << v << " ";cout << endl;system("pause");return 0;
}
// 对于自定义数据类型,set容器必须指定排序规则
#include <iostream>
#include <set>
using namespace std;class Person
{friend ostream& operator<<(ostream& out, const Person& p);friend class ComparePerson;
public:Person(string name, int age) {this->m_Name = name;this->m_Age = age;}
private:string m_Name;int m_Age;
};ostream& operator<<(ostream& out, const Person& p) {out << "姓名: " << p.m_Name << " 年龄: " << p.m_Age;return out;
}class ComparePerson
{public:// 按照年龄降序排序 bool operator()(const Person& p1, const Person& p2) const {return p1.m_Age > p2.m_Age;}
};int main()
{// 对于自定义数据类型,必须指定排序规则set<Person, ComparePerson> s;Person p1("刘备", 30);Person p2("关羽", 27);Person p3("张飞", 24);Person p4("赵云", 21);s.insert(p1);s.insert(p2);s.insert(p3);s.insert(p4);for (auto p : s)cout << p << endl;system("pause");return 0;
}

2. map / multimap

  • map / multimap属于关联式容器,底层结构是用红黑树实现
  • map中所有元素都是pair,第一个元素为键值,起到索引作用,第二个元素为实际值
  • 所有元素都会根据元素的键值自动按升序排序
  • map不允许容器中有重复键值元素,multimap允许容器中有重复键值元素
  • 对于自定义数据类型,map容器必须指定排序规则
// 基本使用
#include <iostream>
#include <map>
using namespace std;int main()
{map<int, int> m;// 插入m.insert(pair<int, int>(1, 10));m.insert(make_pair(2, 20));m.insert(map<int, int>::value_type(3, 30));// 不建议使用[]插入m[4] = 40;// 如果没有这个键,就创建这个键值对,值为0m[5];for (const auto& p : m)cout << p.first << " " << p.second << " ";    // 1 10 2 20 3 30 4 40 5 0// 可以用于访问cout << m[1] << endl;    // 10// 删除m.erase(m.begin());       // 2 20 3 30 4 40 5 0m.erase(5);                // 2 20 3 30 4 40// 容器是否为空if (m.empty()) {cout << "map为空" << endl;}else {// 返回容器中元素的数目cout << "map的大小为: " << m.size() << endl;}// 按键查找map<int, int>::iterator pos = m.find(3);// 按键统计// 对于map,结果为0或者1int num = m.count(3);cout << "num = " << num << endl; // 1system("pause");return 0;
}
// 更改排序方式
#include <iostream>
#include <map>
using namespace std;class MyCompare {public:bool operator()(int v1, int v2) const {return v1 > v2;}
};int main()
{map<int, int, MyCompare> m;m.insert(make_pair(1, 10));m.insert(make_pair(2, 20));m.insert(make_pair(3, 30));m.insert(make_pair(4, 40));m.insert(make_pair(5, 50));for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {cout << "key = " << it->first << " value = " << it->second << endl;}system("pause");return 0;
}

参考:https://www.bilibili.com/video/BV1et411b73Z

【C++】STL容器相关推荐

  1. C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)

    C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...

  2. C++拾趣——STL容器的插入、删除、遍历和查找操作性能对比(Windows VirtualStudio)——遍历和删除

    相关环境和说明在<C++拾趣--STL容器的插入.删除.遍历和查找操作性能对比(Windows VirtualStudio)--插入>已给出.本文将分析各个容器中遍历和查找的性能.(转载请 ...

  3. C++拾趣——STL容器的插入、删除、遍历和查找操作性能对比(Windows VirtualStudio)——删除

    相关环境和说明在<C++拾趣--STL容器的插入.删除.遍历和查找操作性能对比(Windows VirtualStudio)--插入>已给出.本文将分析从头部.中间和尾部对各个容器进行删除 ...

  4. C++拾趣——STL容器的插入、删除、遍历和查找操作性能对比(ubuntu g++)——遍历和查找

    相关环境和说明在<C++拾趣--STL容器的插入.删除.遍历和查找操作性能对比(ubuntu g++)--插入>已给出.本文将分析各个容器中遍历和查找的性能.(转载请指明出于breakso ...

  5. C++拾趣——STL容器的插入、删除、遍历和查找操作性能对比(ubuntu g++)——删除

    相关环境和说明在<C++拾趣--STL容器的插入.删除.遍历和查找操作性能对比(ubuntu g++)--插入>已给出.本文将分析从头部.中间和尾部对各个容器进行删除的性能.(转载请指明出 ...

  6. STL容器存储的内容动态分配情况下的内存管理

    主要分两种情况:存储的内容是指针:存储的内容是实际对象. 看以下两段代码, typedef pair<VirObjTYPE, std::list<CheckID>*> VirO ...

  7. STL容器是否是线程安全的

    转载http://blog.csdn.net/zdl1016/article/details/5941330 STL的线程安全. 说一些关于stl容器的线程安全相关的话题. 一般说来,stl对于多线程 ...

  8. gdb 查看 stl容器 zz

    将下面文件作为 ~/.gdbinit的内容, 或者在已有的~/.gdbinit中source下面的文件, 然后可以以下列方式查看stl容器的数据:  容器类型 GDB 命令 std::vector&l ...

  9. 标准非STL容器 : bitset

    1. 概念 什么是"标准非STL容器"?标准非STL容器是指"可以认为它们是容器,但是他们并不满足STL容器的所有要求".前文提到的容器适配器stack.que ...

  10. c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件

    Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...

最新文章

  1. tf.keras.losses.BinaryCrossentropy 损失函数 示例
  2. ubuntu18.04.4 安装 qq x64 版本
  3. 音视频出海,如何乘风破浪?
  4. 张量的通俗理解和计算
  5. sqoop连接mysql_sqoop安装
  6. 《计算复杂性:现代方法》——第0章 记 号 约 定 0.1 对象的字符串表示
  7. spring boot2 坑 - 解决cros跨域问题
  8. (十六)企业部分之lvs
  9. ListView 优化
  10. orCAD16.6 PSPICE DC Sweep 增加y轴
  11. Typescript配置Jest测试框架
  12. JVM——垃圾回收算法
  13. python if简洁写法_Python - if-else 的多种简洁写法
  14. c# Npoi导出Excel并合并行列
  15. css3 特效大全,CSS3 特效范例整理
  16. MySQL中IN和EXISTS的用法
  17. 【MapReduce】使用MapReduce实现PageRank算法
  18. 抄码器视频教程牛羊抄码器冷库抄码机进口牛羊肉冷库冷冻肉抄码器怎么设置
  19. VPython三维仿真(NO.3) 导入复杂模型
  20. 301 302状态码【重定向】

热门文章

  1. 2021-2027全球与中国空气监测设备市场现状及未来发展趋势
  2. 【软考】【知识产权与法律法规】
  3. golang的开源游戏服务器框架
  4. 还在羡慕微信/微博的图片处理?-android酷炫图片处理(下)
  5. 一次ajax多次回调结果,使用jQuery中的when实现多个AJAX请求对应单个回调的例子分享...
  6. 【C语言】初识C语言——认识第一个C语言程序
  7. Matlab--intersect
  8. Interlaced Sparse Self-Attention for Semantic Segmentation
  9. 计算机应用基础中课程表怎么制作,浅谈《计算机应用基础》课程中Word表格的制作课程教学...
  10. Btree/B+tree原理及区别(详解)