一、容器
序列式容器
每个元素都有固定的位置,–取决于插入时机和地点,和元素值无关。
vector
deque
list
stack
queue
关联式容器
元素位置取决于特定的排序准则,和插入顺序无关。
set
multiset
map
multimap
二、迭代器
迭代器提供对一个容器中对象的访问方法,并定义了容器中对象的范围。
通过迭代器统一了对所有容器的访问方式
vector<int>::iterator iter;
迭代器失效
插入元素后失效
插入元素后,容器搬迁了,迭代器指向的原地址失效。
删除元素后失效
vector<int> v1 = { 1,2,3,3,3,4,5 };
for (vector<int>::iterator it = v1.begin(); it != v1.end(); ++it)
{
//当删除一个元素后,后面的元素前移动,迭代器指向原来的位置,++it会跳过一个元素,导致错误
if (*it == 3)
{
//删除一个元素后,回跳到原来位置的上一个位置,++it后,即回到了原来位置,不会错过元素。
it = v1.erase(it) - 1;
}
}
三、vector
单端数组,随机存取
构造函数
#include <iostream>
#include <vector>
int main() {
// 默认构造函数
std::vector<int> vec1;
// 带有元素数量和默认值的构造函数
std::vector<int> vec2(5, 10); // 创建一个包含5个元素,每个元素的值为10
// 使用迭代器范围的构造函数
std::vector<int> vec3{1, 2, 3, 4, 5};
std::vector<int> vec4(vec3.begin(), vec3.end());
// 复制构造函数
std::vector<int> vec5(vec4);
// 移动构造函数(C++11及以后版本)
std::vector<int> vec6(std::move(vec5));
// 初始化列表构造函数(C++11及以后版本)
std::vector<int> vec7 = {1, 2, 3, 4, 5};
// 带有分配器参数的构造函数
std::allocator<int> alloc;
std::vector<int, decltype(alloc)> vec8(alloc);
return 0;
}
赋值
#include <iostream>
#include <vector>
int main() {
// 创建两个vector
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
// 使用赋值运算符将vec2赋值给vec1
vec1 = vec2;
// 使用assign成员函数和迭代器范围进行赋值
std::vector<int> vec3 = {1, 2, 3};
std::vector<int> vec4 = {4, 5, 6};
vec3.assign(vec4.begin(), vec4.end());
// 使用assign成员函数和重复值进行赋值
std::vector<int> vec5 = {1, 2, 3};
vec5.assign(5, 10); // 将5个元素的值都设置为10
//使用swap交换两个容器的元素
vec1.swap(vec2);
return 0;
}
大小
//返回容器中元素的个数
vector.size();
//判断容器是否为空
vector.empty();
//重新指定容器的长度为num,若容器变长,则以默认值填充新位置,如果容器变短,超出容器长度的元素被删除。
vector.resize(num);
//重新指定容器的长度,若容器变长,则以elem值填充新位置,如果容器变短,则超出位置的元素被删除
vector.resize(num,elem);
数据的读取
//返回索引idx所指的数据,如果idx越界,抛出out_of_range异常
vector.at(idx);
//返回索引idx所指的数据,越界时,运行直接报错
vector[idx];
数据的插入和删除
尾部插入和删除
//在容器尾部加入一个元素num
vector.push_back(num);
//在容器尾部删除一个元素
vector.pop_back();
中间插入
//在pos位置插入一个elem元素的拷贝,返回新数据的位置
vector.insert(pos,elem); //pos不能为下标,应该为指针
//在pos位置插入n个elem数据,无返回值
vector.insert(pos,n,elem);
//在pos位置插入[beg,end)区间的数据,无返回值
vector.insert(pos,beg,end);
四、deque
双端数组,随机存取、地址不一定连续
比 vector 多了两个函数
//在头部插入一个元素
deque.push_front(elem);
//删除头部第一个元素
deque.pop_front();
五、list
双向链表容器、双向迭代器、不支持随机存取、不支持at(pos)函数和[ ]操作符
带参构造
//将n个elem拷贝给本身
list(n,elem);
//区间构造
list(begin,end); //注意“左闭右开”原则
//拷贝构造
list(const list &lst);
插入删除元素
和 deque 差不多
数据存取
//返回第一个元素
list.front();
//返回最后一个元素
list.back();
正/反向 迭代器
//正向
list.begin();
list.end();
//反向 需要使用 reverse_iterator 迭代器
list.rebegin();
list.rend();
赋值
//将区间中数据拷贝赋值给本身
list.assign(begin,end);
//将n个elem拷贝赋值给本身,覆盖之前的值
list.assign(n,elem);
//重载等号操作符
list& operator=(const list &lst);
//将list与本身的元素互换
list.swap(lst);
容器大小
//返回容器中元素的个数
list.size();
//判断容器是否为空
list.empty();
//重新指定容器的长度为num,默认值填充新位置
list.resize(num);
//重新指定容器长度为num,若容器变长,用elem填充(不覆盖)
list.resize(num.elem);
元素插入
//在pos位置插入elem,返回新数据的位置 (pos为迭代器)
list.insert(pos,elem);
//在pos插入 n 个elem,无返回值(pos为迭代器)
list.insert(pos,n,elem);
//在pos位置插入[beg,end)区间的数据,无返回值(pos为迭代器)
list.insert(pos,beg,end);
元素删除
//删除容器中所有元素
list.clear();
//删除(beg,end)区间的数据,返回下一个数据的位置
list.erase(beg,end);
//删除pos位置的数据,返回下一个数据的位置
list.erase(pos);
//删除容器中所有与elem匹配的元素
list.remove(elem);
反序排列
//将容器中的元素反序
list.reverse();
list迭代器失效
删除节点导致失效
//正确用法
list<int> ls = { 1,2,3,3,4,5,6 };
for (list<int>::iterator it = ls.begin(); it != ls.end();)
{
if (*it == 3)
{
//返回删除元素的下一个元素的迭代器
it = ls.erase(it);
}
else
{
it++;
}
}
六、stack
先进后出、没有迭代器、不允许遍历、
进出栈
//栈顶插入元素elem
stack.push(elem);
//删除栈顶元素
stack.pop();
访问
//返回栈顶元素
stack.top();
拷贝和构造方法
//拷贝构造
stack(const stack &stk);
//重载等号操作符
stack& operator=(const stack &stk);
容器的大小
//返回栈的大小
stack.size();
//判断栈是否为空
stack.empty();
七、queue
先进先出、没有迭代器、不能遍历
进出元素
//插入一个元素
queue.push(elem);
//删除一个元素
queue.pop();
访问
//访问队首元素
queue.front();
拷贝构造和赋值
//拷贝构造
queue(const queue &qu);
//重载等号操作符
queue operator=(const que ue &qu);
大小
//返回队列大小
queue.size();
//判断队列是否为空
queue.empty();
八、set
采用红黑树实现、插入删除比vector快、元素是唯一的、集合中的元素按一定的顺序排列、实现去重功能、
不能使用at(pos)与[ ]、
set 每个元素只能出现一次,multiset 中 同一值可以出现多次
不可以修改set或multiset中的元素值,因为该容器是自动排序的
插入与迭代器
//在容器中插入元素elem
set.insert(elem);
//正向迭代器
set.begin();
set.end();
//反向迭代器
set.rbegin();
set.rend();
拷贝构造和赋值
//拷贝构造函数
set(const set &st);
//重载等号操作符
set& operator=(const set &st);
//交换两个集合容器
set.swap(st);
大小
//返回元素个数
set.size()
//判空
set.empty();
删除
//清除所有元素
set.clear();
//删除pos迭代器所指元素,返回下一个元素的迭代器
set.erase(pos); //不支持反向迭代器
//删除[beg,end)区间的元素
set.erase(beg,end);
//删除容器中值为elem的元素 有这个元素返回true,没有返回false
set.erase(elem);
元素排序
//该容器按照升序方式排列
set<int, less<int>> setIntA;
//该容器按照降序方式排列
set<int,greater<int>> setIntB;
自定义类型和指定排序
自定义类
重载()操作符,指定排序方式
定义容器
查找
//查找elem,返回elem的迭代器
set.find(elem);
//返回容器中elem的元素个数,
set.count(elem);
//返回第一个值>=elem元素的迭代器
set.lower_bound(elem);
//返回第一个>elem元素的迭代器
set.upper_bound(elem);
pair对组
//返回容器中与elem相等的上下限两个迭代器,[beg,end),两个迭代器封装在pair对组中,
set.equal_range(elem);
//定义pair对组接收返回值
pair<set<int>::iterator, set<int>::iterator> p = set.equal_range(elem);
//访问pair对组
pair.first;
pair.second
九、map
存储的键值对,map<int, char> mapA;
实列
创建一个学生类
创建map容器
插入元素
方式一
//往容器中插入元素,返回pair
map.inset();
方式二
//通过value_type的方式插入对象
map.insert(map<int,string>::value_type(1,"小张"));
方式三
//通过数组的方式插入值
map[3] = "小李";
如果键值对存在则是修改,不存在则是插入。
迭代遍历
获取键对应的值
//方式一
使用[]
//方式二
使用find()函数,成功返回对应的迭代器,失败返回end()的返回值
map<int, string> ::iterator it = map.find(3);
//方式三
使用at()函数,如果键值对不存在会抛出“out_of_range 异常”