c++stl——容器
阅读提示:
看到这篇文章的大部分学者应该是学习了有关数据结构的知识的,所以关于顺序容器的特点我并没有写出来。如果你不是特别了解,你可以看我之前写的关于数据结构的文章。
目录
一、容器
1.1、顺序容器
1.1.1vector(动态数组)
1.1.2list(链表)
1.1.3queue(队列)
1.1.4stack(栈)
1.1.5array数组
1.2、关联容器
1.2.1set
1.2.2map
一、容器
1.1、顺序容器
1.1.1vector(动态数组)
1、基本概念
vector是一个模板类,存储在连续的内存空间中,因此它可以通过下标([])访问其中的元素。
2、头文件
#include<vector>
3、定义与初始化
vector<int>A; //默认构造
vector<double>B(4); //长度为4
vector<char>C(10, '#'); //长度为10,默认值为#
vector<int>D = { 1,2,3,4,5,6 }; //初始化列表进行初始
A = D; //拷贝
4、常用操作
a)添加元素
- push_back:像容器的末尾添加一个元素。
- insert:在容器中的指定位置插入一个元素。
vector<int> vec = {1, 2, 3,4};
vec.push_back(5); // 添加元素5到末尾
// 在第二个位置插入元素7
vec.insert(vec.begin() + 1,7);
b) 访问元素
- 使用下标(
[]
)来访问指定位置的元素。 - 使用at() 来安全地访问元素,若越界则抛出异常。
- 使用front()来返回容器中第一个元素。
- 使用back()来返回最后一个元素。
vector<int>A = { 1,2,3,4,5,6 }; //初始化列表进行初始
cout < <A.at(0) << endl; //1
cout << A.at(3) << endl; //4
cout << A[4] << endl; //5
cout << A.front() << endl; //1
cout << A.back() << endl; //6
c)删除元素
- pop_back:删除容器末尾的元素。
- clear:清空容器中所有元素。
d)获取长度
- size()返回容器中当前存储的元素个数。
- capacity():返回容器的容量,即当前容器可以容纳的最大元素数。
- resize():重新设置容器大小。
1.1.2list(链表)
1、基本概念
list是一个序列容器,可以存储在非相邻的内存中,list容器底层为带头双向循环链表。
2、头文件
#include<list>
3、定义与初始化
list<int>L1; //默认构造
vector<int>a = { 1,2,3,4,5 };
list<int>L2(a.begin(), a.end()); //区间构造
list<int>L3(L2); //拷贝构造
list<int>L4(6, 9); //带参构造,意为6个9存入list容器
4、常用操作
a)添加
- push_back():在链表尾部插入元素。
- push_front():在链表头部插入元素。
- insert():在指定位置插入元素。
#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main() {
vector<int>a = {1,2,3,4,5};
list<int>L(a.begin(), a.end()); //区间构造
L.push_front(0); //头部插入0
L.push_back(7); //尾部插入7
auto ptr = L.begin();
advance(ptr, 6); //移到第7的位置
L.insert(ptr, 6); //在第7的位置上插入6
list<int>::iterator it = L.begin(); //迭代器iterator
while (it != L.end()) {
cout << *it << endl;
it++;
}//01234567
return 0;
}
b)访问
- front():访问链表头部的元素。
- back():访问链表尾部的元素。
c)删除
- pop_front():删除链表头部元素。
- pop_back():删除链表尾部元素。
- erase():删除指定位置元素。
- remove():删除所有等于指定值的元素。
#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main() {
vector<int>a = {1,2,2,3,4,4,5};
list<int>L(a.begin(), a.end()); //区间构造
L.pop_front(); //1
L.pop_back(); //5
L.erase(L.begin()); //2
L.remove(4); //4,4
list<int>::iterator it = L.begin(); //迭代器iterator
while (it != L.end()) {
cout << *it << endl;
it++;
}//2,3
return 0;
}
d)大小
- size():返回链表中元素个数。
- empty():判断是否为空
- resize():重新指定容器的长度。
e)反转和排序
- reverse():反转链表中的元素顺序。
- sort():对链表元素进行排序。
#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main() {
vector<int>a = {2,9,2,3,1,7,4,8,5,11,6,10};
list<int>L(a.begin(), a.end()); //区间构造
L.sort(); //默认为从小到大
list<int>::iterator it = L.begin(); //迭代器iterator
while (it != L.end()) {
cout << *it <<" " ;
it++;
}//1 2 2 3 4 5 6 7 8 9 10 11
cout << endl;
L.reverse(); //翻转
for (int i : L) {
cout << i << " ";
}//11 10 9 8 7 6 5 4 3 2 2 1
return 0;
}
1.1.3queue(队列)
1、基本概念
queue是队列,遵循先进先出的原则。
2、头文件
#include<queue>
3、初始化
queue<int>Q1;
4、常用操作
a)添加
- push():在队尾插入一个元素
b)访问
- front():访问队列第一个元素
- back():访问对队列最后元素
注:queue容器没有提供迭代器
c)删除
- pop():移除队列第一个元素。
d)获取大小
- size():返回元素个数
- empty():判断是否为空
#include<iostream>
#include<list>
#include<queue>
using namespace std;
int main() {
queue<int>q;
q.push(1);
q.push(2);
cout<<q.front()<<q.back()<<endl; //1,2
q.pop(); //1
q.size(); //1
return 0;
}
1.1.4stack(栈)
1、基本概念
stack是栈,提供了后进先出的数据结构。
2、头文件
#include<stack>
3、定义与初始化
stack<int>S; //S为栈名
4、常用操作
a)添加
- push():向栈顶添加元素。
b)访问
- top():返回栈顶元素,且不移除。
注意:stack不支持直接遍历或随机访问,因为它是一个容器适配器,设计上遵循栈的 LIFO(后进先出)原则。
c)删除
- pop():移除栈顶元素。
d)访问大小
- empty():判断栈是否为空。
- size():返回栈中元素的数量。
#include<iostream>
#include<stack>
using namespace std;
int main() {
stack<int>S; //S为栈名
S.push(1);
S.push(2);
S.push(3);
S.pop();
cout << S.size() << endl; //2
while (!S.empty()) {
cout << S.top();
S.pop();
}//2,1
return 0;
}
1.1.5array数组
1、基本概念
array是一种容器,提供了固定大小序列的封装。
2、头文件
#include<array>
3、定义与初始化
array<int, 10> arr; // 声明一个包含10个整数的数组(未初始化)
array<int, 3> arr2 = { 1, 2, 3 }; // 声明并初始化数组
4、常用操作
a)添加
- fill():用指定值来填满数组
b)访问
- at():访问指定值。
- front():访问第一个元素。
- back():访问最后一个元素。
c)获取大小
-
size():返回数组的大小。
-
empty()检查数组是否为空(对于array,只有在大小为 0 时才为空)。
#include<iostream>
#include<array>
using namespace std;
int main() {
array<int, 3> arr= { 1, 2, 3 }; // 声明并初始化数组
//cout << arr.front() << arr.at(1) << arr.back() << endl; //1,2,3
//array<int, 3>::iterator it; //这个是错误的
for (auto it = arr.begin(); it < arr.end();it++) {
cout << *it << endl;
}//123
arr.fill(7);
cout << arr[0] << arr[2] << endl; //7,7
return 0;
}
1.2、关联容器
1.2.1set
1、基本概念
set中存储唯一的元素集合,且元素是有序的,在set中,元素的值同时也充当了键(key)的角色。
2、特点
1)唯一性:不存在存储重复的元素。
2)有序性:按照特定的顺序存储,默认是升序。
3)自动排序:set内部实现的是黑红树,所以元素插入会自动排序。
4)非直接访问性:不可以用索引的方式直接访问。
3、头文件
#include<set>
4、定义与初始化
set<int>st; //默认构造
set<int>st2{ 1,2,7,8 }; //初始化
set<int>st3(st2); //拷贝
5、常用操作
a)插入
- insert():插入元素。
b)访问
- find():它通过给定的键值在集合中查找元素,并返回一个指向该元素的迭代器。如果元素不存在,则返回 end()迭代器。
c)删除
- erase():删除元素。
- clear():清空容器。
d)获取大小
- size():返回元素个数。
- empty():判断是否为空。
- clear():清空容器。
#include<iostream>
#include<set>
using namespace std;
int main() {
set<int>st{ 1,2,7,8 }; //初始化
st.insert(3);
st.insert(6); //插入元素
st.insert(5);
st.insert(4);
st.insert(4); //因为set具有唯一性,所以这次插入不会有任何效果
//查找
auto p = st.find(3);
if (p != st.end()) {
cout << "找到" << endl;
}
else {
cout << "没找到" << endl;
}
//遍历一
auto q = st.find(4); //q是返回的迭代器
while (q != st.end()) {
cout << *q << " ";
q++;
}//4678
cout << endl;
//遍历二
for (int i : st) {
cout << i << " ";
}//因为set具有有序性,12345678
cout << endl;
//删除
st.erase(5);
st.erase(3);
cout << st.size() << endl; //返回元素个数
//迭代器
set<int>::iterator it = st.begin();
while (it != st.end()) {
cout << *it << " ";
it++;
}//删除后,124678
cout << endl;
st.clear();
cout << st.size() << endl; //清空,0
return 0;
}
1.2.2map
1、基本概念
map存储了键值对,其中每个键值对都是唯一,在map中,键用于唯一地标元素,而值是于键关联的数据。
2、特点
1)唯一键:map中不会存储重复键,每个键对应一个值。
2)有序性:键总是按照特定的顺序存储,默认是升序。
3)自动排序:map会自动按照间的顺序排序。
4)键值对访问:可以直接通过键来访问对应的值。
3、头文件
#include<map>
4、定义与初始化
map<int, string,greater<int>>m; //greater实现降序排序
map<int, string>m1; //默认升序
map<int, string>m2 = { {1,"hello"},{2,"hi"},{3,"good"} }; //初始化
map<int, string>m3(m2); //拷贝
vector<pair<int, string>>v = { {1,"hello"},{2,"hi"},{3,"good"} };
map<int, string>m4(v.begin(), v.end()); //范围初始化
5、常用操作
a)插入
- insert():插入元素。
- emplace():可以直接构造元素,避免不必要的拷贝或移动操作。
b)访问
- find():它通过给定的键值在集合中查找元素,并返回一个指向该元素的迭代器。如果元素不存在,则返回 end()迭代器.
- at():使用键来访问元素,如果键不存在,会抛出out_of_range 异常。
- []:用键来访问,如果键不存在,会创建一个新的键值对并初始化(如0,空字符串)。
c)删除
- erase():删除元素。
- clear():清除元素。
d)获取大小
- size():返回元素个数。
- empty():判断是否为空。
6、知识补充
pair 是 C++ 标准库中的一个模板类,用于将两个值组合成一个单一对象。它通常用于需要返回两个值或将两个值作为一个整体处理的场景。
#include<iostream>
#include<map>
using namespace std;
int main() {
map<int, string,greater<int>>m; //默认,greater实现降序排序
map<int, string>m2 = { {1,"hello"},{2,"hi"},{3,"good"} }; //初始化
//遍历
auto it = m2.begin();
while (it != m2.end()) {
cout << it->first << " " << it->second << endl;
it++;
}
//插入
m[1] = "你好";
m.insert({ 2,"早安" });
m.insert(pair<int, string>(3, "午安"));
m.emplace(4, "晚安");
//访问
//1,find
auto p = m.find(3);
if (p != m.end()) {
cout << "找到" << endl;
}
else {
cout << "没找到" << endl;
}
//2,at
try {
cout<< m.at(2) << endl; //早安
}
catch (out_of_range) {
cout << "not found" << endl;
}
//3,[]
cout << m[1] << endl; //你好
//删除
//1, erase
auto q = m.find(1);
m.erase(q); //
m.erase(3);
//clear清空
m.clear();
//大小
cout << m.size() << endl;
return 0;
}