C++STL容器常见用法大总结(快速复习上手版)

一、顺序型容器

1.1 vector

动态数组,在内存中开辟一块连续空间,容量为capacity。追加元素至容器大小size超出容量capacity时,自动扩容。

#include <vector>  // 添加头文件

1.1.1 初始化方法

// 默认构造函数,v1=[]
vector<int> v1;

// v2 = [0, 0, 0, 0, 0]
vector<int> v2(5);

// v3 = [123, 123, 123, 123, 123]
vector<int> v3(5, 123);

// v4 = [1, 2, 3, 4]
vector<int> v4{1, 2, 3, 4};
vector<int> v4 = {1, 2, 3, 4};

// 拷贝构造函数, v5 = [1, 2, 3, 4]
vector<int> v5(v4);
vector<int> v5 = v4;
vector<int> v5(v4.begin(), v4.end());

// 二维数组,10行8列,元素为0
vector<vector<int>> v6(10, vector<int>(8, 0));

1.1.2 赋值

直接赋值或使用assign函数,基本等同于初始化方法。

vector<int> v;
v = {1, 2, 3, 4}
v = v4;
v.assign(v4.begin(), v4.end());
v.assign(5, 123);

1.1.3 插入、删除、引用

引用,通过下标返回任意元素,通过函数返回首尾元素的引用

vector<int> v = {1, 2, 3, 4};
v.front() = 100;
v[1] = 200;
v.at(2) = 300;
v.back() = 400;
// v = [100, 200, 300, 400]

直接在尾部插入、删除元素(没有push_front()pop_front()

v.push_back(123);  // v = [100, 200, 300, 400, 123]
v.pop_back();      // v = [100, 200, 300, 400]

通过迭代器在任意位置插入、删除元素(慎用,时间复杂度高,涉及到元素的搬移)

vector<int> v2 = {1, 2, 3, 4};
v.insert(v.end(), {500, 600});              // v = [100, 200, 300, 400, 500, 600]
v.insert(v.begin(), v2.begin(), v2.end());  // v = [1, 2, 3, 4, 100, 200, 300, 400, 500, 600]
v.insert(v.begin(), 0);                     // v = [0, 1, 2, 3, 4, 100, 200, 300, 400, 500, 600]
v.insert(v.end(), 2, 700);                  // v = [0, 1, 2, 3, 4, 100, 200, 300, 400, 500, 600, 700, 700]

v.erase(v.begin());                         // v = [1, 2, 3, 4, 100, 200, 300, 400, 500, 600, 700, 700]
v.erase(v.begin(), v.begin()+4);            // v = [100, 200, 300, 400, 500, 600, 700, 700]

1.1.4 查看大小、容量、是否为空

v.empty();      // 判断是否为空 v.size()==0
v.clear();      // 清空容器

v.size();       // 返回大小
v.capacity();   // 返回容量

v.resize(5);    // 重置size,如果扩容填充默认值,如果缩小则截断
v.reserve(10);  // 重置capacity,强制扩容,如果缩小不做任何操作

1.1.5 遍历

vector<int> v = {0, 1, 2, 3, 4};

// 1. 通过下标遍历
for (int i = 0; i < v.size(); ++i) {
	cout << i << " " << v[i] << endl;
}

// 2. 通过迭代器遍历
for (vector<int>::iterator iter = v.begin(); iter != v.end(); ++iter) {
	cout << *iter << " ";
}
for (auto iter = v.begin(); iter != v.end(); ++iter) {
	cout << *iter << " ";
}

// 3. C++11新增,for遍历
for (auto value: v) {
	cout << value << " ";
}

1.1.6 算法(排序、去重、查找)

需包含头文件 #include <algorithm>
排序 sort() , 倒序reverse()

vector<int> v = {2, 1, 4, 4, 3};

bool cmp(const int& a, const int& b) {
	return a > b;
}

reverse(v.begin(), v.end());               // v = [3, 4, 4, 1, 2]

sort(v.begin(), v.end());                  // v = [1, 2, 3, 4, 4] 原位升序排序,结合快排、插入排序、堆排序等多种排序方式,根据数据量等因素自动选择
sort(v.begin(), v.end(), cmp);             // v = [4, 4, 3, 2, 1] 自定义比较函数
sort(v.begin(), v.end(), greater<int>());  // v = [1, 2, 3, 4, 4]
sort(v.begin(), v.end(), less<int>());     // v = [4, 4, 3, 2, 1]

去除相邻重复元素 unique(),通常结合sort()erase()使用

sort(v.begin(), v.end());
auto end_unique = unique(v.begin(), v.end());  // 返回第一个重复元素的位置
erase(end_unique, v.end());                    // v = [1, 2, 3, 4]

查找最值max_element()min_element()

auto max_iter = max_element(v.begin(), v.end());  // *max_iter = 4
auto min_iter = min_element(v.begin(), v.end());  // *min_iter = 1

查找元素find(),查找上界upper_bound(),查找下界lower_bound()

vector<int> v = {1, 2, 2, 3, 5, 5, 7};

auto find_iter1 = find(v.begin(), v.end(), 6);  // find_iter1 == v.end()
auto find_iter2 = find(v.begin(), v.end(), 2);  // find_iter2 == v.begin() + 1

auto lower_iter = lower_bound(v.begin(), v.end(), 5);  // lower_iter - v.begin() = 4
auto upper_iter = upper_bound(v.begin(), v.end(), 5);  // upper_iter - v.begin() = 6

1.2 deque

双向开口的连续内存空间,如果需要频繁在首尾增删元素,使用dequevector性能更好。
deque由多段连续内存衔接而成,因此没有容量的概念,也没有重新分配内存的操作。当首端或尾端容量不足时,直接新分配一段内存并连接到当前内存上。
deque内存分配

1.2.1 插入删除

初始化、赋值、排序、查找等操作与vector基本相同;插入删除比vector新增了头部的push_front()pop_front()

#include <deque>
deque<int> dq = {1, 2, 3, 4};

dq.push_back(5);    // dq = [1, 2, 3, 4, 5]
dq.pop_back();        // dq = [1, 2, 3, 4]

dq.push_front(0);    // dq = [0, 1, 2, 3, 4]
dq.pop_front();        // dq = [1, 2, 3, 4]

1.3 forward_list / list

链表

#include <forward_list>  // 单向链表
#include <list>          // 双向链表

头部插入删除 push_front(), pop_front()
尾部插入删除 push_back(), pop_back()
任意位置插入删除 insert(), erase()

list<int> ls = {1, 3, 5, 7};
ls.push_back(9);     // ls = [1, 3, 5, 7, 9]
ls.pop_back();       // ls = [1, 3, 5, 7]

ls.push_front(0);    // ls = [0, 1, 3, 5, 7]
ls.pop_front();      // ls = [1, 3, 5, 7]

ls.insert(ls.begin(), 0);  // ls = [0, 1, 3, 5, 7]
ls.erase(ls.end());        // ls = [0, 1, 3, 5]

遍历:通过双向访问迭代器(只能++,不能+=n)(只能 !=,不能 <=)

for (auto iter = ls.begin(); iter != ls.end(); ++iter) {
    cout << *iter << " ";
}

二、关联型容器

2.1 set / multiset / unordered_set / unordered_multiset

  • 集合,分别 #include <set>, #include <multiset>, #include <unordered_set>, #include <unordered_multiset>
  • unordered_setunordered_multiset无序,setmultiset有序,使用红黑树自动保持元素顺序。
  • set不允许元素重复,multiset允许元素重复。

2.1.1 初始化

set<int> st = {2, 1, 1, 2, 3, 4, 4, 4};  // st = [1, 2, 3, 4]

2.2.2 插入、删除、查询

插入方法insert(),删除方法erase()新增了根据元素值删除的重载函数。

st.insert(5);    // st = [1, 2, 3, 4, 5]
st.insert(4);    // st = [1, 2, 3, 4, 5]

st.erase(st.begin());  // st = [2, 3, 4, 5]
st.erase(5);           // st = [2, 3, 4]

auto iter = st.find(5);    // iter == st.end()
int num = st.count(5);     // num == 0

2.2 map / multimap / unordered_map / unordered_multimap

基本同set系列,unordered_map经常被用作哈希表/字典。

2.2.1 初始化、赋值、访问

unordered_map<int, string> hashmap;

hashmap[0] = "apple";
hashmap.insert(pair<int, string>(1, "banana"));
hashmap.insert(make_pair<int, string>(2, "orange"));
hashmap.insert(unordered_map<int, string>::value_type(3, "grape"));

2.2.2 遍历

for (auto iter = hashmap.begin(); iter != hashmap.end(); ++iter) {
	cout << iter->first << " " << iter->second << endl;
}

三、容器适配器

  • 底层默认用deque实现
  • 因为进出的顺序是固定的,所以增删方法都是push()pop(),不加front/back
  • 对于栈和优先队列(可以想象为堆)只能取出一头的元素,所以引用元素用top();而对于队列是先进先出的水平结构,所以取出元素用front()back()

3.1 stack

栈,先进后出。

#include <stack>
stack<int> stk;

stk.push(1);
stk.pop();
int value = stk.top();

3.2 queue

队列,先进先出。

#include <queue>
queue<int> que;

que.push(1);
int f = que.front();
int b = que.back();
que.pop();

3.3 priority_queue

优先队列,先进先出同时保持队首元素最大,使用堆结构。

#include <queue>
priority_queue<int> pq;

pq.push(2);
pq.push(3);
pq.push(4);

int value = pq.top();  // value = 4
pq.pop();              // pq = [3, 2]

  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值