文章目录
容器适配器
1.stack
栈是一种容器适配器,实现栈的底层容器是deque
#include<stack>
stack<int> s; //声名栈(模板类)的数据类型
s.empty(); //如果栈为空则返回true, 否则返回false;
s.size(); //返回栈中元素的个数
s.top(); //返回栈顶元素, 但不删除该元素
s.pop(); //弹出栈顶元素, 但不返回其值
s.push(); //将元素压入栈顶
2.queue
队列是一种容器适配器,实现队列的底层容器是deque,也可以用其他容器比如vector、list。
#include <queue>
queue<int> q; //声名队列(类模板)数据类型
q.empty() //如果队列为空返回true,否则返回false
q.size() //返回队列中元素的个数
q.pop() //删除队列首元素但不返回其值
q.front() //返回队首元素的值,但不删除该元素
q.push() //在队尾压入新元素
q.back() //返回队列尾元素的值,但不删除该元素
3.priority_queue
自定义比较方式
struct cmp{
bool operator()(arg...)
{...}
}
常用操作
priority_queue<node*,vector<node*>,cmp>q; //指定vector作为容器
q.top(); //返回优先级最高元素
q.push(); //压入元素
q.pop(); //弹出元素
q.empty();
容器
1.list
#include <list>
list<int> l1,l2;
l1.begin(); //获取指向链表头部元素的迭代器
l1.end(); //获取指向链表最后一个元素下一个位置的迭代器
l1.empty();
l1.front(); //获取链表头部的数据,注意先判断链表是否为空
l1.back(); //获取链表尾部的数据,注意先判断链表是否为空
l1.push_back(); //在尾部增加数据
l1.push_front(); //在头部增加数据
l1.pop_back(); //删除链表尾部的数据
l1.pop_front(); //删除链表头部的数据
l1.insert(l1.begin(),l2.begin(),l2.end()); //插入多个数据,从l1.begin()位置开始,插入从l2.begin()到l2.end()(不会取到)的所有数据
l1.erase(l1.begin(),l1.end()); //将l1.begin()到l1.end()的所有数据删除,只写第一个参数就是只删除第一个参数位置的数据
l1.resize(); //改变链表大小,若变小,会把超出的部分删除
l1.size() //返回链表元素个数
l1.clear(); //清除列表
l1.remove(i); //删除指定值的元素
l1.sort(); //升序排列
l1.reverse(); //倒序排列
l1.merge(l2); //把l1,l2两个链表按升序方式合并
2.vector
//初始化
vector<int> vec //默认初始化,为空
vector<int> vec2(vec); //使用vec初始化vec2
vector<int> vec3(3); //初始化3个值为0的元素
vector<int> vec4(4, 1); //初始化4个值为1的元素
vector<string> vec5(5,"null"); //初始化5个值为null的元素
//常用操作
vec.push_back(3); //向末尾添加元素3
vec.pop_back(); //删除末尾元素
vec.begin(); //返回指向首元素的迭代器
vec.end(); //返回指向末尾下一位置的迭代器
vec.size(); //一共的元素个数
vec.empty(); //判断是否为空
vec[i] //下标
vec.insert(vec.end(),5,3); //从末尾下一位置插入5个值为3的元素
vec.erase(vec.begin(),vec.end());//删除之间的元素,其他元素前移
cout<<(vec==vec2)?true:false; //判断是否相等==、!=、>=、<=...
vector<int>::iterator iter = vec.begin(); //获取迭代器首地址
vector<int>::const_iterator c_iter = vec.begin(); //const类型迭代器
vec.clear(); //清空元素
//遍历方法
//下标法(vector的特有访问方法,一般容器只能通过迭代器访问)
int len = vec1.size();
for(int i=0;i<len;i++)
cout<<vec1[i];
cout<<endl<<endl;
//迭代器法
vector<int>::const_iterator iterator = vec1.begin();
for(; iterator != vec1.end(); iterator++)
cout<<*iterator;
//赋值与swap
vector<string> vs1(3); // vs1有3个元素
vector<string> vs2(5); // vs2有5个元素
vs1.swap(vs2); //执行后,vs1中5个元素,而vs2则存3个元素
3.deque
#include<deque>
deque<int> d; //声名双端队列(类模板)的数据类型
d.push_back(1); //把数据增加在队尾
d.push_front(1); //把数据增加在队首
d.pop_front(); //把队首的数据删除
哈希结构
当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。
- array(数组)
- set(集合)
- map(映射)
set的三种数据结构其底层实现与优劣:
集合 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::set | 红黑树 | 有序 | 否 | 否 | O(log n) | O(log n) |
std::multiset | 红黑树 | 有序 | 是 | 否 | O(log n) | O(log n) |
std::unordered_set | 哈希表 | 无序 | 否 | 否 | O(1) | O(1) |
set的缺点:占用空间大,速度慢(set把数值映射到key上要做hash计算)
unordered_set
//初始化
unordered_set<int> nums_set(nums1.begin(),nums1.end());//nums1是vector<int类型>
//常用操作
nums_set.find(num)!=nums_set.end() //find()返回一个迭代器
nums_set.insert(num); //添加元素到集合中
nums_set.erase(num); //删除元素
map的三种数据结构其底层实现与优劣:
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
---|---|---|---|---|---|---|
std::map | 红黑树 | 有序 | 否 | 否 | O(log n) | O(log n) |
std::multimap | 红黑树 | 有序 | 是 | 否 | O(log n) | O(log n) |
std::unordered_map | 哈希表 | 无序 | 否 | 否 | O(1) | O(1) |
unordered_map
#include <unordered_map>
unordered_map<string,int> umap; //定义
umap.insert(Map::value_type("test", 1));//增加
//根据key删除,如果没找到n=0
auto n = umap.erase("test") //删除
auto it = umap.find(key) //改
if(it != umap.end())
it->second = new_value;
//map中查找x是否存在
umap.find(x) != map.end()
umap.count(x) != 0
//C++中pair的应用
pair<T1,T2>(xx,xx)//将两个数据组合成一组数据
算法
#include<algorithm>
sort(); //快速排序(升序)
reverse(); //反序
swap(); //交换两个元素
count(); //在序列中统计某个值出现的次数
find(); //在序列中找出某个值第一次出现的位置
copy(); //从序列的第一个元素起复制
merge(); //合并两个有序序列
min(); //返回两个元素的小值
max(); //返回两个元素的大值
总结
总结了一下常用STL容器、容器适配器的用法,方便自己查阅使用。
文章部分内容参考自Reference article