一、顺序性容器
1、vector:
可变大小数组。相当于数组,可动态构建,支持随机访问,无头插和尾插,仅支持inset插入,除尾部外的元素删除比较麻烦。但使用最为广泛。
· 头文件:
#include <vector>
· 构造函数:
一般前两种用的比较多。
//1.默认构造,无参构造
vector<int> v1;
for (int i = 0; i < 10; ++i)
{
v1.push_back(i);
}
PrintVector(v1);
//2.利用区间方式构造
vector<int> v2(v1.begin(), v1.end());
PrintVector(v2);
//3.n个element方式构造
vector<int> v3(10, 100); //10个100
PrintVector(v3);
//4.拷贝构造
vector<int> v4(v3);
PrintVector(v4);
· 赋值操作:
//直接赋值
vector<int> v2;
v2 = v1;
//assign赋值
vector<int> v3;
v3.assign(v1.begin(), v1.end());
//n个element赋值
vector<int> v4;
v4.assign(10, 100);
· 插入和删除:
插入主要是使用push_back(),也可使用insert();删除操作主要是pop_back(),也可使用erase()
vector<int> v;
//尾插
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);
PrintVector(v);
//尾删
v.pop_back();
PrintVector(v);
//插入 - 提供迭代器
v.insert(v.begin(), 100);
PrintVector(v);
//重载
v.insert(v.begin(), 2, 100);
PrintVector(v);
//删除 - 提供迭代器
v.erase(v.begin());
PrintVector(v);
//重载
v.erase(v.begin(), v.end()); //相当于清空操作
PrintVector(v);
v.clear(); //清空容器中所有元素
PrintVector(v);
· 容量和大小:
对于容量用的是capacity(),对于大小是size(),当然你也可以用resize()来改变其大小,不过在此之前都需用empty()这个函数来判断一下容器是否为空;
2、deque:
双端队列。支持头插、删,尾插、删,随机访问较vector容器来说慢,但对于首尾的数据操作比较方便。
· 头文件:
#include <deque>
· 构造函数:
deque的构造函数与vector类似,也是四种常见的方式。
deque<int> d1;
for (int i = 0; i < 10; ++i)
{
d1.push_back(i);
}
deque<int> d2(d1);
deque<int> d3(10, 100);
deque<int> d4;
d4 = d3;
· 赋值操作:
deque<int> d1;
for (int i = 0; i < 10; ++i)
{
d1.push_back(i);
}
deque<int> d2;
d2 = d1;
deque<int> d3;
d3.assign(d1.begin(), d1.end());//将[beg, end)区间中的数据拷贝赋值给本身
deque<int> d4;
d4.assign(10, 100);
· 大小和容量:
deque容器无capacity()函数。
if (d1.empty())
{
cout << "deque容器为空" << endl;
}
else
{
cout << "deque容器不为空" << endl;
cout << "deque容器的大小为:" << d1.size() << endl;
//deque容器无capacity - 容量
}
//改变大小
//d1.resize(15);
d1.resize(15,1);
print(d1);
d1.resize(5);
print(d1);
· 插入和删除:
//首尾操作
deque<int> d;
d.push_back(10);
d.push_back(20); //尾插
d.push_front(100);
d.push_front(200); //头插
print(d); //200 100 10 20
d.pop_back(); //尾删
d.pop_front(); //头删
print(d); //100 10
d.insert(d.begin(), 100);
print(d); //100 100 10
d.insert(d.begin(), 2, 900);
print(d); //900 900 100 100 10
· 数据存取:
这里主要是区别[]方式和at()函数的访问情况。
deque<int> d;
d.push_back(10);
d.push_back(20);
d.push_back(30);
d.push_front(100);
d.push_front(200);
d.push_front(300);
//通过[]方式访问
for (int i = 0; i < d.size(); ++i)
{
cout << d[i] << " ";
}
cout << endl;
//通过at访问
for (int i = 0; i < d.size(); ++i)
{
cout << d.at(i)<< " ";
}
cout << endl;
cout << "第一个元素为:" << d.front() << endl;
cout << "最后一个元素为:" << d.back() << endl;
3、list:
双向循环链表。使用起来很高效,对于任意位置的插入和删除都很快,在操作过后,以后指针、迭代器、引用都不会失效。
· 头文件:
#include <list>
· 构造函数:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将n个elem拷贝给本身。
· 赋值操作:
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
swap(lst);//使用之后实现将lst与本身的元素互换。
· 插入和删除操作:
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。
4、forward_list:
单向链表。只支持单向访问,在链表的任何位置进行插入/删除操作都非常快。
5、array:
固定数组。vector的底层即为array数组,它保存了一个以严格顺序排列的特定数量的元素。
· 头文件:
#include <array>
二、关联式容器
1、set / mutliset:
集合/多重集合。对于set,在使用insert插入元素时,已插入过的元素不可重复插入,这正好符合了集合的互异性,在插入完成显示后,会默认按照升序进行排序,对于multiset,可插入多个重复的元素。
· 头文件:
#include <set>
· 查找和统计操作:
find() 和 count()
2、map / mutlimap:
映射/多重映射。二者均为二元关联容器(在构造时需要写两个参数类型,前者对key值,后者对应value值),因为有两个参数,因此在插入元素的时候需要配合对组pair进行插入,具体见深入详解。
· 头文件:
#include <map>
· 构造和赋值:
map<int, int> m; //键值对
//第一个:key(键值) 第二个:value(实值)
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20)); //依旧会按照顺序排列
m.insert(pair<int, int>(4, 40));
m.insert(pair<int, int>(5, 30));
print(m);
//拷贝构造
map<int, int> m2(m);
print(m2);
//赋值
map<int, int> m3;
m3 = m2;
print(m3);
· 大小和交换:
//大小
map<int, int> m;
//第一个:key(键值) 第二个:value(实值)
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20)); //依旧会按照顺序排列
m.insert(pair<int, int>(4, 40));
m.insert(pair<int, int>(4, 80)); //无效
print(m);
if (m.empty())
{
cout << "map容器为空" << endl;
}
else
{
cout << "map容器不为空" << endl;
cout << "map容器的大小为:" << m.size() << endl;
}
· 查找和统计:
map<int, int> m;
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.insert(make_pair(3, 40));
print(m);
map<int, int>::iterator pos = m.find(3);
if (pos!=m.end())
{
cout << "找到到元素了,key=" << pos->first << " value=" << pos->second << endl;
}
else
{
cout << "没有找到改元素" << endl;
}
int num = m.count(3);
cout << "num=" << num << endl;
//map不允许插入重复元素,对于count统计而言,要么为0,要么为1
//mutilmap的count统计可能>1
· 插入和删除:
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;
//[]不建议插入,可以用key来访问value
cout << m[5] << endl;
print(m);
//删除
m.erase(m.begin());
print(m);
m.erase(3); //根据键值key来删除
print(m);
m.erase(m.begin(), m.end());
print(m);
m.clear();
print(m);