STL

114 阅读5分钟

引言

本文主要走一下STL中常用的一些容器和算法,参考wyqz.top/p/870124582…

vector

vector原型是动态的数组,在内存空间中连续存放,存取在常数空间中完成,在尾端进行增加或者删除的容器。

头文件:#include<vector>

初始化
//一维初始化
vector<int> a;   //初始化一个int类型的数组
vector<float> b;   //float类型
vector<node> c;   //结构体
//指定长度和初始值
vector<int> v(n);    //n为长度,初始化下标为0~n-1的n个数,且全为0
vector<int> v(n, 1);  //n个数全部为1
//多个元素
vector<int> a{1, 2, 3, 4, 5};   //大小为5,初始化每一个元素
//拷贝构造
vector<int> a(n, 0);
vector<int> b(a);       //拷贝构造,b和a一样

//二维初始化
vector<vector<int>> v;   //二维数组v
//指定构造
vector<vector<int>> a(n + 1, vector<int>(m + 1, 0));   //n+1行,每一行有m+1个数,每个数都是0
方法函数
v.front();       //返回第一个元素
v.back();        //返回最后一个元素
v.pop_back();       //弹出最后一个元素
v.push_back(ele);   //尾部插入一个元素
v.size();           //返回实际元素个数
v.clear();          //清空所有的元素
v.resize(n, v);     //指定大小为n,不足的用v元素补满
v.insert(it, x);    //往迭代器插入it插入元素x
v.erase(first, last);   //删除[first,last)中的所有的数据
v.begin();             //返回首元素的迭代器
v.end();               //返回最后一个元素的下一个迭代器
v.empty();             //返回是否为空
访问
vector<int> v = { 1,2,3,4,5 };
//下表访问
for (int i = 0; i < v.size(); i++)
{
    cout << v[i] << " ";
}
cout << endl;
//迭代器访问
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
    cout << *it << " ";
}
cout << endl;
//智能指针
for (auto val : v)
{
    cout << val <<" ";
}

B4KIAM[VUD64B_~E8F8TAND.png

stack

栈是一个非顺序的容器,满足先进后出,后进先出的特性:

头文件为:#include<stack>

初始化
stack<int> st;   //保存int
stack<string> st;   //保存string
stack<node> st;    //结构体
方法函数
st.push(ele);   //元素进栈
st.pop();       //出栈
st.top();       //返回最后一个元素
st.empty();     //判断是否为空
st.size();      //返回数量
访问/遍历

只能一个一个的访问弹出。

queue

先进先出的结构

头文件:#include<queue>

初始化
queue<int> q;    
queue<node> q;  //结构体
方法函数
q.front();    //返回队首元素
q.back();     //返回队尾元素
q.push(ele);  //尾部插入ele
q.pop();      //头部弹出元素
q.size();     //返回元素个数
q.empty();    //判断是否为空
访问/遍历

同样不能支持随机访问,也是访问一个弹出一个。

deque

头部和尾部都可以插入的队列

头文件:#include<deque>

初始化
deque<int> de;
deque<node> de;
方法函数
deque<int> dq;
dq.push_back(ele);    //尾部插入ele
dq.push_front(ele);   //头部插入ele
dq.front();         //返回头部元素
dq.back();          //返回尾部元素
dq.pop_back();      //弹出尾部元素
dq.pop_front();     //弹出头部元素
dq.erase(it);       //删除迭代器it指向的元素
dq.erase(it first, it last);   //删除迭代器[first,lats)的元素
dq.empty();      //判断是否为空
dq.size();       //判断数量
dq.clear();      //清空
访问/遍历

和普通的队列没有什么多大区别。

优先队列(priority_queue)

在正常的队列中加入优先级,每次输出最小的或者最大的元素的队列,它的底层是堆来实现的:

头文件:#include<queue>

初始化
priority_queue<int> pri_que;   //默认大根堆,每次取出的是最大值
priority_queue<int, vector<int>, greater<int>> pri_que;   //小堆,每次输出的是最小值

参数解释,第一个参数是保存的数据的类型,第二个是底层存储的容器,第三个参数是逻辑,less<int>表示数字大的优先级大,先输出,greater<int>表示数组小的优先级大,先输出。

方法函数
pri_que.top();   //返回当前的优先级最高的元素(首元素)
pri_que.push(ele);   //插入元素
pri_que.pop();    //弹出优先级最高的元素
pri_que.size();   //返回当前的数量
pri_que.empty();   //判断是否为空
复杂排序

先写常用的基础写法:

priority_queue<int> pri_que;  //默认大堆
priority_queue<int, vector<int>, less<int>> pri_que;   //大堆,每次输出最大值
priority_queue<int, vector<int>, greater<int>> pri_que;   //小堆,每次输出的是最小值

自定义排序

struct cmp1 {
	bool operator()(int x, int y)
	{
		return x > y;
	}
};
struct cmp2 {
	bool operator()(int x, int y)
	{
		return x < y;
	}
};
priority_queue<int, vector<int>, cmp1> q1;  //小堆
priority_queue<int, vector<int>, cmp2> q2;  //大堆

结构体排序

struct node
{
	int x, y;
};
struct cmp
{
	bool operator()(const node& a, const node& b)
	{
		return a.x < b.x;
	}
};
priority_queue<node, vector<node>, cmp> pri_que;   //优先输出小的

pair类型

pair中按照first降序排序,second进行升序排序。

priority_queue<pair<int, int> >q;

map

map类似了函数映射的关系,在map中是一一对应的关系,按照键值从小到大进行排序:

头文件:#include<map>

初始化
map<string, string> mp;   //字符串和字符串
map<string, int> mp;     //字符串和数字
map<int, node> mp;     //数字和结构体
方法函数
mp.find(key);  //返回键值为key的迭代器
mp.erase(it);     //删除迭代器it对应的键和值
mp.erase(key);    //更具key删除对应的键和值
mp.erase(it first, it last);  //删除迭代器[first last)
mp.size();     //返回数量
mp.clear();    //清空map所有数量
mp.insert(map);   //插入元素,需要构建键值对
mp.empty();    //判断是否为空
mp.begin();    //返回第一个元素的迭代器
mp.end();      //返回最后一个元素的下一个迭代器
mp.rbegin();    //map元素的最后一个迭代器
mp.rend();     //第一个元素的上一个迭代器
mp.count(key);   //判断是否存在,返回1/0
mp.lower_bound(key);   //返回一个迭代器,指向键值》=key的第一个元素
mp.upper_bound(key);   //返回>key的元素
访问/遍历
map<int, int> mp;
mp[1] = 1,mp[2] = 2, mp[3] = 3;
//向后遍历
auto it = mp.begin();
while (it != mp.end())
{
	cout << it->first << " " << it->second << " " << endl;
	it++;
}
//向前遍历
auto it = mp.rbegin();
while (it != mp.rend())
{
	cout << it->first << " " << it->second << " " << endl;
	it++;
}
//迭代器
for (map<int, int>::iterator it = mp.begin(); it != mp.end(); it++)
{
	cout << it->first << " " << it->second << " " << endl;
}
//只能指针
for (auto i : mp)
{
	cout << i.first << " " << i.second << " " << endl;
}
//单个访问
map<int, int>::iterator it = mp.find(1);
cout << it->first << " " << it->second << " ";
//插入
mp[1] = 1;
mp.insert(make_pair(1, 1));
mp.insert(pair<int, int>(1, 1));
mp.insert({ 1,1 });
同类结构

multimap<int, int> map; 哈希结构:#include<unordered_map>,unordered_map<int, int> mp;

set

set结构中的容器不会重复,当有元素的时候,不会添加,按照从小到大排列:

头文件:#include<set>

初始化
set<int> s;
函数方法