C++之容器总结
1、容器种类:序列、关联容器
2、C++11以前的容器:deque 、list、queue、priority_queue、stack、vector、map、multimap 、set、multiset、bitest
3、C++11新增的容器:forward_list、unordered_map、unordered_multimap、unordered_set、unordered_multiset;
4、容器的概念:存储其它对象的对象,被存储的对象必须是同一种类型。
5、时间复杂度:编译时间>固定时间>线性时间(由快到慢)
6、序列:特殊的容器,7种STL容器类型(deque、forward_list 、queue 、priority_queue 、stack 、vector)

7、序列(容器的详细介绍)
7.1 vector
头文件:
#include<vector>
vector是数组的一种类表示,提供自动内存管理功能,可以动态改变vector对象的长度,可以随着元素的添加和删除而且增大和缩小。提供对元素的随机访问,在尾部添加和删除元素的时间是固定的,但在头部或者中间插入和删除元素的复杂度为线性时间。
vector是可反转容器概念的模型,增加两个类方法:rbegin()和rend(),和bengin()和end()形成对比。
rbegin()返回一个指向反转序列的第一个元素的迭代器rend()返回反转序列的超尾迭代器。
7.2 deque
头文件
#include<deque>
deque模板类表示双端队列,支持随机访问,与vector的主要区别如下:
- deque对象的开始位置插入和删除元素的时间都是固定的,但是vector中为线性时间。
- 由于为了实现在deque两端执行插入和删除操作的时间为固定的这一目的,deque的对象设计比vector对象更为复杂,所以对于随机访问和在序列中执行插入和删除操作,vector容器执行这些操作时速度要快。
7.3 list
头文件
#include<list>
list模板类表示双向链表,与vector的区别:
- list不支持数组表示法和随机访问,强调元素的快速插入和删除;vector强调通过随机访问进行快速访问
- list从容器中插入或删除元素之后,链表迭代器指向元素将不变,
在链表中插入新元素并不会移动已有的元素,而只是修改链接信息。

7.4 forward_list(c++11)
forward_list:单链表,每个节点只链接下一个节点,所以只需要正向迭代器,是不可反转的容器。
7.5 queue
queue:适配器类,不允许随机访问队列元素,不允许遍历队列,可以将元素添加到队尾、从队首删除元素、查看队首和队尾的值,检查元素数目和测试队列是否为空。

7.6 priority_queue
priority_queue:适配器类,支持的操作与queue相同。
与queue的主要区别:
- 在
priority_queue中,最大的元素被移到队首 - 默认的底层类是
vector
7.7 stack
stack是适配器类,给底层类提供了典型的栈接口。``stack模板限制比vector`更多。不允许随机访问,不允许遍历栈,把使用限制在定义栈的基本操作上,可以将栈压入到栈顶,从栈顶弹出元素,查看栈顶的值,检查元素数目和测试栈顶是否为空。

7.8 array
头文件:
#include<array>
array没有定义调整容器大小的操作,定义了对它来说有意义的成员函数,operator[]()和at()
8.关联容器
8.1 关联容器
将值与键关联在一起,并使用键来查找值。提供对元素的快速访问,允许插入新元素,不能插入指定的位置。
关联容器通常用于确定数据放置位置的算法,以便可以快速检索信息。
关联容器是使用某种树实现的,树是一种数据结构,相对于链表,树的查找速度更快。
8.2 STL中提供的4种关联容器:set multiset map multimap
头文件:
#include<set.h>
#include<multiset.h>
#include<map.h>
#include<multimap.h>
8.2.1 四种关联容器
- set :值类型与键相同,键是唯一的
- multiset:可能有多个值的键是相同的
- map:值与键的类型不同,键是唯一的,每个键只对应一个值
- multimap:与map相似,一个键可以与多个值相关联
1、set是关联集合,可反转、可排序、且键是唯一的,所以不能存储多个相同的值,与vector和list类似,set使用模板参数来指定要存储的值类型。
/*
* @Description:
* @version:
* @Author: sunshine
* @Github: https://subshine.github.io/
* @Email: 2182216077@ncepu.edu.cn
* @Date: 2019-11-21 20:38:16
* @LastEditTime: 2020-03-10 15:31:09
*/
// set example
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;
int main() {
const int N = 6;
string s1[N] = { "buf", "think", "for", "heavy", "can", "for" };
string s2[N] = { "metal", "any", "food", "elegant", "deliver", "for" };
set<string> A(s1, s1 + N);
set<string> B(s2, s2 + N);
ostream_iterator<string, char> out(cout, " ");
cout << "Set A: ";
copy(A.begin(), A.end(), out);
cout << std::endl;
cout << "Set B: ";
copy(B.begin(), B.end(), out);
cout << endl;
//std::cout << A.keys() << std::endl;
cout << "Union of A and B:\n";
set_union(A.begin(), A.end(), B.begin(), B.end(), out);//并集
cout << endl;
cout << "Intersection of A and B:\n";
set_intersection(A.begin(), A.end(), B.begin(), B.end(), out);//交集
cout << std::endl;
cout << "Difference of A and B:\n";
set_difference(A.begin(), A.end(), B.begin(), B.end(), out);//获得两个集合的差
cout << endl;
set<string> C; //python中set函数去重
cout << "Set C:\n";
set_union(A.begin(), A.end(), B.begin(), B.end(),
insert_iterator<set<string> >(C, C.begin()));//合并起来按照顺序排列
copy(C.begin(), C.end(), out);
cout << endl;
string s3("grungy");
C.insert(s3);
cout << "Set C after insertion:\n";
copy(C.begin(), C.end(), out);
cout << endl;
cout << "Showing a range:\n";
copy(C.lower_bound("ghost"), C.upper_bound("spook"), out);//截取字母g开头到字母s开头的部分
cout << endl;
return 0;
}
2、multimap
multimap是可反转的,经过排序的关联容器,但是键和值的类型不同,同一个键可能与多个值相关联。
为了将信息结合在一起,实际的值类型将键类型和数据类型结合为一对。STL使用模板类pair<class T,class U>将这两种值存储到一个对象中。
multimap<int,string> codes;
//创建multimap对象,键类型为int,存储的值类型为string
pair<const int,string> item(213,"Los Angeles");
codes.insert(item);
codes.insert(pair<const int,string>(213,"Los Angeles"));
//对于pair对象,可以使用first和second成员来访问其两个部分
cout<<item.first<<" "<<item.second<<std::endl;
//打印区号为718的所有城市
pair<multimap<KeyType,string>::iterator,multimap<KeyType,string>::iterator> range=codes.equal_range(718);
//也可以使用C++11自动类型推导功能
auto range=codes.equal_range(718);
cout<<"Cities with area code 718:\n";
std::multimap<KeyType,std::string>::iterator it;
for(it=range.first;it!=range.second;++it)
{
cout<<(*it).second<<endl;
}
/*
* @Description:
* @version:
* @Author: sunshine
* @Github: https://subshine.github.io/
* @Email: 2182216077@ncepu.edu.cn
* @Date: 2019-11-21 20:38:16
* @LastEditTime: 2020-03-11 10:56:52
*/
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
typedef int KeyType;
typedef std::pair<const KeyType, std::string> Pair;
typedef std::multimap<KeyType, std::string> MapCode;
int main() {
using namespace std;
MapCode codes;
codes.insert(Pair(415, "San Francisco"));
codes.insert(Pair(510, "Oakland"));
codes.insert(Pair(718, "Brooklyn"));
codes.insert(Pair(718, "Staten Island"));
codes.insert(Pair(415, "San Rafael"));
codes.insert(Pair(510, "Berkeley"));
cout << "Number of cities with area code 415: " << codes.count(415)
<< endl;
cout << "Number of cities with area code 415: " << codes.count(718)
<< endl;
cout << "Number of cities with area code 415: " << codes.count(510)
<< endl;
cout << "Area Code City\n";
MapCode::iterator it;
for (it = codes.begin(); it != codes.end(); ++it) {
cout << " " << (*it).first << " " << (*it).second << endl;
}
return 0;
}

9. 无序关联容器
无序关联容器:将值与键关联起来,使用键来查找值。
无序关联容器与关联容器的区别:
- 关联容器是基于树结构的;
- 无序关联容器是基于数据结构哈系表的,提高增加和删除元素的速度以及提高查找算法的效率
无序关联容器:
unordered_setunordered_multisetunordered_mapunordered_multimap
reference: C++primer第六版
本文总结了C++中的容器,包括C++11前后的序列容器如deque、list、vector,以及关联容器如set、map、multiset、multimap。详细介绍了各容器的特点、操作和适用场景,特别关注了C++11新增的forward_list和无序关联容器。

140

被折叠的 条评论
为什么被折叠?



