STL基础--容器
容器种类
- 序列容器(数组,链表)
- Vector, deque, list, forward list, array
- 关联容器(二叉树),总是有序的
- set, multiset根据值排序,元素值不能修改
- map, multimap根据key排序,键值不能修改
- 无序容器(hash 表)
- 无序set/multiset
- 无序map/multimap
序列容器

Vector
vector<int> vec; // vec.size() == 0
vec.push_back(4);
vec.push_back(1);
vec.push_back(8); // vec: {4, 1, 8}; vec.size() == 3
// Vector特定的操作:
cout << vec[2]; // 8 (没有范围检查)
cout << vec.at(2); // 8 (超出范围会抛range_error exception异常)
for (int i; i < vec.size(); i++) {
cout << vec[i] << " ";
for (list<int>::iterator itr = vec.begin(); itr!= vec.end(); ++itr)
cout << *itr << " ";
for (it: vec) // C++ 11
cout << it << " ";
// Vector是内存中一个动态分配的连续的数组
int* p = &vec[0]; p[2] = 6;
// 所有容器共有的一些成员函数
// vec: {4, 1, 8}
if (vec.empty()) { cout << "Not possible.\n"; }
cout << vec.size(); // 3
vector<int> vec2(vec); // 拷贝构造, vec2: {4, 1, 8}
vec.clear(); // 删除所有元素; vec.size() == 0
vec2.swap(vec); // 交换,vec2变成空的,vec有3个元素
// 注:没有抽象带来的开销,非常高效
/* Vector的特性:
* 1. 在末尾插入/删除很快: O(1)
* 2. 在其他地方插入/删除s慢: O(n)
* 3. 搜索慢: O(n)
*/
Deque
deque<int> deq = { 4, 6, 7 };
deq.push_front(2); // deq: {2, 4, 6, 7}
deq.push_back(3); // deq: {2, 4, 6, 7, 3}
// Deque接口跟vector类似
cout << deq[1]; // 4
/* 特性:
* 1. 在首尾插入/删除快
* 2. 中间插入/删除慢: O(n)
* 3. 搜索慢: O(n)
*/
List
* -- 双向链表
* 元素储存在内存不同的地方,cache会经常miss。很多STL实现会将其元素放到一起,但即使如此因为包含了太多指针,会消耗更多的内存(意味着更多的cache miss和page fault)
*/
list<int> mylist = {5, 2, 9 };
mylist.push_back(6); // mylist: { 5, 2, 9, 6}
mylist.push_front(4); // mylist: { 4, 5, 2, 9, 6}
list<int>::iterator itr = find(mylist.begin(), mylist.end(), 2); // itr -> 2
mylist.insert(itr, 8); // mylist: {4, 5, 8, 2, 9, 6}
// O(1), 比vector/deque更快
itr++; // itr -> 9
mylist.erase(itr); // mylist: {4, 8, 5, 2, 6} O(1)
/* 特性:
* 1. 任何地方插入/删除快: O(1)
* 2. 搜索慢: O(n)
* 3. 没有随机访问,即没有 [] 运算符
*/
// 拼接速度快
mylist1.splice(itr, mylist2, itr_a, itr_b ); // O(1)
Array
// 不能改变大小,不能元素个数的Array是不同类型
int a[3] = {3, 4, 5};
array<int, 3> a = {3, 4, 5};
a.begin();
a.end();
a.size();
a.swap();
array<int, 4> b = {3, 4, 5};
关联容器
- 基于二叉树,总是排序的,默认基于 < 排序
- 没有push_back(), push_front()

set和multiset
// 元素不能重复
set<int> myset;
myset.insert(3); // myset: {3}
myset.insert(1); // myset: {1, 3}
myset.insert(7); // myset: {1, 3, 7}, O(log(n))
set<int>::iterator it;
it = myset.find(7); // O(log(n)), it指向7
// 序列容器没有find函数
pair<set<int>::iterator, bool> ret;
ret = myset.insert(3); // 不插入新元素
if (ret.second==false)
it=ret.first; // "it"当前指向元素3
myset.insert(it, 9); // myset: {1, 3, 7, 9} O(log(n)) => O(1),it作为插入元素位置的一个提示,并不是实际插入位置
// it 指向3
myset.erase(it); // myset: {1, 7, 9}
myset.erase(7); // myset: {1, 9}
// 注:序列容器没有这种根据元素值删除元素的erase
// multiset允许元素重复的set
multiset<int> myset;
// set/multiset: 元素值都是不能修改的
*it = 10; // *it只读
/* 特性:
* 1. 搜索快: O(log(n))
* 2. 因为也是通过指针联系(cache miss和page fault的问题),遍历慢 (相比vector & deque)
* 3. 没有随机访问,即没有 [] 运算符
*/
map和multimap
/*
* map
* - key值不能重复
*/
map<char,int> mymap;
mymap.insert ( pair<char,int>('a',100) );
mymap.insert ( make_pair('z',200) );
map<char,int>::iterator it = mymap.begin();
mymap.insert(it, pair<char,int>('b',300)); // "it"只是一个提示
it = mymap.find('z'); // O(log(n))
// showing contents:
for ( it=mymap.begin() ; it != mymap.end(); it++ )
cout << (*it).first << " => " << (*it).second << endl;
// multimap允许键值重复
multimap<char,int> mymap;
// map/multimap:
// -- 键值不能修改
// type of *it: pair<const char, int>
(*it).first = 'd'; // Error
// 为何叫“关联”容器
// 因为value和key是关联的,set是特殊的map,value等于key
无序容器(C++ 11)
- 无序的set/multiset
- 无序的map/multimap
- 顺序是未定义的,可能随时间改变


/*
* 基本类型和string都定义了默认的hash函数
*
* 没有下标操作[]和at()
* 没有push_back()和push_front()
*/
unordered_set<string> myset = { "red","green","blue" };
unordered_set<string>::const_iterator itr = myset.find ("green"); // O(1)
if (itr != myset.end()) // 重要的检查
cout << *itr << endl;
myset.insert("yellow"); // O(1)
vector<string> vec = {"purple", "pink"};
myset.insert(vec.begin(), vec.end());
// Hash表特定的APIs:
cout << "load_factor = " << myset.load_factor() << endl; // 负载因子:总元素和总桶数的比值
string x = "red";
cout << x << " is in bucket #" << myset.bucket(x) << endl; // x位于哪个桶
cout << "Total bucket #" << myset.bucket_count() << endl; // 总的桶数
// 无序multiset,无序map和multimap也是类似
// hash冲撞 => 性能退化
/* 无序容器的特性:
* 1. 在任何位置搜索/插入都最快: O(1)
* 关联容器O(log(n))
* vector, deque O(n)
* list插入O(1) , 搜索O(n)
* 2. Unorderd set/multiset: 元素值不能改变
* Unorderd map/multimap: key不能改变
*/
Associative Array
/*
* 一般指的是map和unordered map
*/
unordered_map<char, string> day = {{'S',"Sunday"}, {'M',"Monday"}};
cout << day['S'] << endl; // 没有范围检查
cout << day.at('S') << endl; // 有范围检查
vector<int> vec = {1, 2, 3};
vec[5] = 5; // Compile Error
day['W'] = "Wednesday"; // Inserting {'W', "Wednesday}
day.insert(make_pair('F', "Friday")); // Inserting {'F', "Friday"}
day.insert(make_pair('M', "MONDAY")); // key已经存在,插入失败
day['M'] = "MONDAY"; // 可以通过下标修改值
void foo(const unordered_map<char, string>& m) {
//m['S'] = "SUNDAY";
//cout << m['S'] << endl; //编译出错,下标操作有写权限,编译器看到以为要对const变量进行写操作
auto itr = m.find('S'); //使用find替代
if (itr != m.end())
cout << *itr << endl;
}
foo(day);
//关于Associative Array:
//1. 搜索时间: unordered_map, O(1); map, O(log(n));
//2. 但是Unordered_map可能退化为O(n);
//3. 不能使用multimap和unordered_multimap, 它们的key不唯一,也没有下标操作[]
容器适配器
- 为了满足某种特殊需要,提供受限制的接口
- 通过基本的容器类实现
*
* 1. 栈 stack: LIFO, push(), pop(), top()
*
* 2. 队列 queue: FIFO, push(), pop(), front(), back()
*
* 3. 优先级队列 priority queue: 第一个元素总是具有最高优先级
* push(), pop(), top()
*/
另一种容器分类的方法
*
* 1. 基于数组的容器: vector, deque
*
* 2. 基于结点的容器: list + associative containers + unordered containers
*
* 基于数组的容器会使指针失效:
* - 原生指针,迭代器,引用
*/
vector<int> vec = {1,2,3,4};
int* p = &vec[2]; // p points to 3
vec.insert(vec.begin(), 0);
cout << *p << endl; // 2, or ?
// 运气好,打印2;运气不好,未定义
STL基础--容器的更多相关文章
- STL List容器
转载http://www.cnblogs.com/fangyukuan/archive/2010/09/21/1832364.html 各个容器有很多的相似性.先学好一个,其它的就好办了.先从基础开始 ...
- STL之容器适配器queue的实现框架
说明:本文仅供学习交流,转载请标明出处,欢迎转载! 上篇文章STL之容器适配器stack的实现框架已经介绍了STL是怎样借助基础容器实现一种经常使用的数据结构stack (栈),本文介绍下第二种STL ...
- STL之容器适配器stack的实现框架
说明:本文仅供学习交流,转载请标明出处,欢迎转载! 一提到适配器(adapter).我们就想到了早期用电话线上网所用的调制解调器,俗称"猫"."猫"的作用是实现 ...
- c++复习:STL之容器
1 STL的string 1 String概念 string是STL的字符串类型,通常用来表示字符串.而在使用string之前,字符串通常是用char*表示的.string与char*都可以用来表示字 ...
- 详解C++ STL priority_queue 容器
详解C++ STL priority_queue 容器 本篇随笔简单介绍一下\(C++STL\)中\(priority_queue\)容器的使用方法和常见的使用技巧. priority_queue容器 ...
- 2.7 C++STL list容器详解
文章目录 2.7.1 引入 2.7.2代码示例 2.7.3代码运行结果 总结 2.7.1 引入 STL list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的.这意味着,list 容 ...
- C++ STL vector容器学习
STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...
- STL基础知识
一,STL的组成 1.什么是STL STL(Standard Template Library)标准模板库的简称,是由惠普开发的一系列软件的总称,STL现在是C++的一部分,已经被构建于编译系统之内, ...
- STL的容器算法迭代器的设计理念
1) STL的容器通过类模板技术,实现数据类型和容器模型的分离. 2) STL的迭代器技术实现了遍历容器的统一方法:也为STL的算法提供了统一性. 3) STL的函数对象实现了自定义数据类型的算法运算 ...
随机推荐
- Dij_heap__前向星。
//前向星 struct node { int nxt; int val; int lst; node () {} node (int next, int value) : nxt(next), va ...
- 阿里云ECS服务器购买流程 (自定义配置购买、按月、按量购买)教程
阿里ECS云服务器自定义购买流程 本文提供全图文流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- Oracle使用笔记(一)
目录 一.创建表: 二.编辑表数据: 三.Oracle基本数据类型: (一) 字符串类型 1.1:CHAR类型 CHAR(size [BYTE | CHAR]) 1.2: NCHAR类型 1.3 VA ...
- java-抽象类的成员特点
1.成员变量:既可以是变量,也可以是常量.abstract不能修饰成员变量. 2.构造方法:有.用于子类访问父类数据的初始化. 3.成员方法:既可以是抽象的,也可以是非抽象的. - 抽象方法:强制要求 ...
- Kubernetes学习
DNS for Services and Pods Services 创建基本的Service kind: Service spec.clusterIP: 为一组相同的服务的Pod集群提供一个虚拟ip ...
- python os模块使用笔记(更新)
import os 添加os模块 walk方法: os.walk(path) path是string形式的目标目录 生成一个某目录下递归树形目录迭代器,方便递归访问子目录,访问目录就能够轻松访问子文件 ...
- Intellij部署Tomcat问题
Intellij部署Tomcat问题 Warnings:No artifacts marked for development 切换到Development标签页 选择+按钮,并选择Artifacts ...
- 【添加tomcat里lib下的jar包】eclipse中The project cannot be built until build path errors are resolved
问题描诉:在eclipse中新建了一个web项目,把myeclipse中正常的项目拷贝到eclipse的src和webcontent目录 然后项目中就出现了× 注意项目中Errors
- What's New In Zeebe: Scaling Zeebe, New Client APIs, Faster Requests, Timestamps, NodeJS Client, and Default Topic is Back!
Written by Daniel Meyer on May 16 2018 in the What's New In Zeebe category. Welcome to the first-eve ...
- Stream processing with Apache Flink and Minio
转自:https://blog.minio.io/stream-processing-with-apache-flink-and-minio-10da85590787 Modern technolog ...