unordered
unordered_set
1.头文件
#include<unordered_set>
2.特征:
1)直接存储数据的值,不是键值对的形式
2)容器内部存储的元素值互不相等且不能修改
3)不会对内部存储数据进行排序
4)不能有重复元素
5)迭代器至少是向前迭代器
3.常用函数
empty(); //判断是否为空
find(); //找到返回迭代器,失败返回end()
count(2); //返回2出现的次数
clear(); //清空容器
swap(); //交换两个容器中的数据
insert(); //传入一个参数(待插入元素) 两个参数(迭代器(指定元素的被插入位置)+待插入元素)
emplace(); //插入元素(转移构造),效率比insert高
erase(); //删除元素
unordered_map
1.头文件
#include<unordered_map>
2.特征
1)允许通过key值快速索引到与其对应的value
2)键值通常用于唯一标识元素,而映射值是一个对象,其内容与此键关联,键和映射值的类型可能不同
3)允许使用key作为参数直接访问value
4)迭代器至少是向前迭代器
3.常用函数
unordered_map<int, double> um1; //构造一个key为int类型,value为double类型的空容器
insert(); //um.insert(pair<int, string>(1, "one"));um.insert(make_pair(4, "four"));
erase();
find();
size();
empty();
clear();
swap();
count();
map
与unordered_map的不同点:
1.map基于红黑树,元素有序存储,unordered_map基于散列表,元素无序存储
优先队列
1.头文件:
#include<queue>
2.常用大顶堆和小顶堆
priority_queue<int,vector<int>,greater<int>> pq;//小顶堆
//不写后两个参数,容器默认为vector,大顶堆
priority_queue<int,vector<int>,less<int>> pq; //大顶堆
# 自定义比较器
struct Comparator{
bool operator()(ListNode* a, ListNode *b){
return a->val > b->val;
}
};
3.常用函数
push(element) //插入到队尾
pop()
top()
empty()
size()
emplace(element) //原地构造一个元素并插入队列
4.pair数据类型比较
先比较第一个元素然后比较第二个元素
eg:
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
priority_queue<pair<int, int> > a; --默认是大顶堆
pair<int, int> b(1, 2);
pair<int, int> c(1, 3);
pair<int, int> d(2, 5);
a.push(d);
a.push(c);
a.push(b);
while (!a.empty())
{
cout << a.top().first << ' ' << a.top().second << '\n';
a.pop();
}
}
multiset
1.头文件
#include<set>
2.作用:它可以看成一个序列,插入或删除一个数都能在O(logn)的时间内完成,而且它能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。
3.常用函数总结
//构造,拷贝,析构
set c; //产生一个空的set/multiset,不含任何元素 eg: multiset<int> s;
set c(op); //以op为排序准则,产生一个空的set/multiset
set c1(c2) //产生某个set/multiset的副本,所有元素都被拷贝
set c(beg,end) //以区间[beg,end)内的所有元素产生一个set/multiset
set c(beg,end, op) //以op为排序准则,区间[beg,end)内的元素产生一个set/multiset
c.~set() //销毁所有元素,释放内存
set<Elem> //产生一个set,以(operator <)为排序准则
set<Elem,0p> //产生一个set,以op为排序准则
c.size()
c.empty()
c.max_size()
//特殊的搜寻函数
count (elem) //返回元素值为elem的个数
find(elem) //返回元素值为elem的第一个元素,如果没有返回end()
lower_bound(elem) //返回元素值为elem的第一个可安插位置,也就是元素值 >= elem的第一个元素位置
upper_bound (elem) //返回元素值为elem的最后一个可安插位置,也就是元素值 > elem 的第一个元素位置
equal_range (elem) //返回elem可安插的第一个位置和最后一个位置,也就是元素值==elem的区间
//迭代器相关函数
c.begin() //返回一个随机存取迭代器,指向第一个元素
c.end() //返回一个随机存取迭代器,指向最后一个元素的下一个位置
c.rbegin() //返回一个逆向迭代器,指向逆向迭代的第一个元素
c.rend() //返回一个逆向迭代器,指向逆向迭代的最后一个元素的下一个位置
//插入和删除
c.insert(elem) //插入一个elem副本,返回新元素位置,无论插入成功与否。
c.insert(pos, elem) //安插一个elem元素副本,返回新元素位置,pos为收索起点,提升插入速度。
c.insert(beg,end) //将区间[beg,end)所有的元素安插到c,无返回值。
c.erase(elem) //删除与elem相等的所有元素,返回被移除的元素个数。
c.erase(pos) //移除迭代器pos所指位置元素,无返回值。
c.erase(beg,end) //移除区间[beg,end)所有元素,无返回值。
c.clear() //移除所有元素,将容器清空
4.注意:multiset中元素不可修改,元素可以重复
Prim
class Prim{
private:
//核心数据结构,存储[横切边]的优先级队列
//三元组{from,to,weight}表示一条边
priority_queue<vector<int>,vector<vector<int>>, greater<vector<int>>> pq;
//类似visited数组的作用,记录哪些节点已经成为最小生成树的一部分
vector<bool> inMST;
int weightSum = 0;
vector<vector<int>>* graph;
public:
Prim(vector<vector<int>>* graph){
this->graph = graph;
int n =graph.size();
this->inMST.resize(n);
//随便从一个点开始切分都可以,这里从节点0开始
inMST[0] = true;
cut(0);
while(!pq.empty()){
vector<int> edge = pq.top();
pq.pop();
int to = edge[1];
int weight = edge[2];
if(inMST[to]){
continue;
}
weightSum += weight;
inMST[to] = true;
cut(to);
}
}
void cut(int s){
for(vector<int>& edge : (*graph)[s]){
int to = edge[1];
if(inMST[to]){
//相邻节点to已经在最小生成树中,skip
//否则这条边会产生环
continue;
}
pq.push(edge);
}
}
int weightSum(){
return weightSum;
}
bool allConnected(){
for(bool connected : inMST){
if(!connected)
return false;
}
return true;
}
};
并查集Union-Find
class UF{
private:
int count; //连通分量数目
int *parent; //存储每个节点的父节点
public:
UF(int n){
this->count = n;
parent = new int[n];
for(int i = 0; i < n; i++){
parent[i] = i;
}
}
void union_(int p, int q){
int rootP = find(p);
int rootQ = find(q);
if(rootP == rootQ)
return;
parent[rootQ] = rootP; //两个连通分量合并成一个
count--;
}
bool connected(int p, int q){
int rootP = find(p);
int rootQ = find(Q);
return rootP == rootQ;
}
//状态压缩
int find(int x){
if(parent[x] != x){
parent[x] = find(parent[x]);
}
return parent[x];
}
int count_(){
return count;
}
}