一、vector
用法一:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> v;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
v.push_back(x);
}
for (int i = 0; i < n; i ++ )
{
cout << v[i] << ' ';
}
puts("");
//sort(v.begin(), v.end(), less<int>()); //排序 从小到大 默认的是此方式
sort(v.begin(), v.end(), greater<int>()); //排序 从大到小
for (int e : v)
{
cout << e << ' ';
}
puts("");
reverse(v.begin(), v.end()); //逆序
for (int e : v)
{
cout << e << ' ';
}
return 0;
}
/**
5
2 5 1 7 6
2 5 1 7 6
7 6 5 2 1
1 2 5 6 7
**/
用法二:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> v;
struct edge{
int u, v, w;
bool operator< (const edge &t) const //重载小于号
{
return w < t.w;
}
};
vector<edge> es; //边集
int main()
{
int m, a, b, c;
cin >> m;
for (int i = 1; i <= m; i ++ )
{
cin >> a >> b >> c;
es.push_back({a, b, c});
}
sort(es.begin(), es.end()); //排序
//遍历方式1
for (int i = 0; i < es.size(); i ++ )
{
printf("%d %d %d\n", es[i].u, es[i].v, es[i].w);
}
//遍历方式2
//for (auto e : es)
//{
// printf("%d %d %d\n", e.u, e.v, e.w);
//}
return 0;
}
/**
4
1 2 8
1 3 1
1 4 6
3 4 5
1 3 1
3 4 5
1 4 6
1 2 8
**/
二、stack
用法一:
#include <iostream>
#include <stack>
using namespace std;
stack<int> s;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ )
{
int x;
cin >> x;
s.push(x);
}
while (s.size())
{
cout << s.top() << endl;
s.pop();
}
return 0;
}
/**
5
2 5 6 7 9
9
7
6
5
2
**/
用法二:
#include <iostream>
using namespace std;
//数组模拟栈
int s[10000], top;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ )
{
int x;
cin >> x;
s[ ++ top] = x;
}
while (top)
{
cout << s[top] << endl;
top --; //维护栈顶指针
}
return 0;
}
/**
5
2 5 6 7 9
9
7
6
5
2
**/
三、queue
用法一:做树的遍历
#include <iostream>
#include <queue> //不用引入vector是因为queue中含有vector
using namespace std;
const int N = 1e5 + 10;
vector<int> e[N];
int vis[N]; //去重数组
queue<int> q;
void bfs()
{
vis[1] = 1; //标记1走过
q.push(1); //1加入队列
while(q.size()) // 当队列不空的时候
{
int x = q.front();
q.pop();
cout << x << endl;
for (auto y : e[x])
{
if (vis[y]) continue; //搜索过就停止
vis[y] = 1; //不然就标记为搜索
q.push(y); //放入队列
}
}
}
int main()
{
int n, m, a, b;
cin >> n >> m;
for (int i = 0; i < m; i ++ )
{
cin >> a >> b;
e[a].push_back(b);
e[b].push_back(a); //加边
}
bfs();
return 0;
}
/**
5 4
1 2
1 3
2 4
2 5
1
2
3
4
5
**/
四、priority_queue
大根堆做排序从大到小,默认是此方式
#include <iostream>
#include <queue> // priority_queue是被包含在queue中的
using namespace std;
priority_queue<int> q; // 默认是大根堆
int n;
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
q.push(x);
}
while (q.size())
{
cout << q.top() << ' ';
q.pop();
}
return 0;
}
/**
5
8 9 1 3 2
1 2 3 8 9
**/
不改变比较方式从小到大
#include <iostream>
#include <queue> // priority_queue是被包含在queue中的
using namespace std;
priority_queue<int> q; // 默认是大根堆
int n;
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
q.push(-x);
}
while (q.size())
{
cout << -(q.top()) << ' ';
q.pop();
}
return 0;
}
/**
5
8 9 1 3 2
1 2 3 8 9
**/
小根堆从小到大
#include <iostream>
#include <queue> // priority_queue是被包含在queue中的
using namespace std;
//priority_queue<int> q; // 默认是大根堆
priority_queue<int, vector<int>, greater<int>> q; // 大根堆 + greater<int>() 小根堆
int n;
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
q.push(x);
}
while (q.size())
{
cout << q.top() << ' ';
q.pop();
}
return 0;
}
/**
5
8 9 1 3 2
1 2 3 8 9
**/
五、unordered_set
用法:
#include <iostream>
#include <unordered_set>
using namespace std;
unordered_set<int> s;
int main()
{
int n, c, x;
cin >> n;
while (n -- )
{
cin >> c >> x;
if (c == 1) s.insert(x); //1是插入操作 2是查询操作
else
{
s.count(x)? puts("Yes"): puts("No");
}
}
return 0;
}
/**
5
1 6
1 2
1 7
2 6
2 5
Yes
No
**/
六、unordered_map
#include <iostream>
#include <unordered_map>
using namespace std;
unordered_map<string, int> map;
int main()
{
int n, c;
string str;
cin >> n;
while (n -- )
{
cin >> c >> str;
if (c == 1) map[str] ++; //1是插入操作 2是查询操作
else
{
if (map.count(str))
{
printf("%d\n", map[str]);
}
else
{
puts("No");
}
}
}
return 0;
}
/**
5
1 dx
1 abc
1 dx
1 aaa
2 dx
2 ab
2
**/
七、一图汇总STL
1.堆的删除和push中包含着上浮下下沉所以是logn的复杂度.
2.有序集合的复杂度是logn的原因是底层的实现原理是红黑树,跟树的深度有关。
3.无序集合的实现方式是,hash表,hash函数如果构造的好就是常数,构造的差就是o(n)的复杂度,通常来说无序集合比有序集合的方法执行的效率要高很多,hash碰撞一般是非常少的。
4.有序键值对映射,就相当于字典一样,键作为排序的依据,也是用红黑树实现都是logn的复杂度。
5.it是一个迭代器,指针指向这个元素的存储位置进行删除。
6.无序键值对也是用hash表来实现的,访问通常都是常数级别的。