queue(队列)
queue是一种先进先出的数据结构。
queue提供了一组函数来操作和访问元素,但它的功能相对较简单。
push(x):在队尾插入元素 x
pop():弹出队首元素
front():返回队首元素
back():返回队尾元素
empty():检查队列是否为空
size0:返回队列中元素的个数
priority_queue(优先队列)
priority_queue与普通队列不同,priority_queue中的元素是按照一定的优先级进行排序的。默认情况下,priority_queue按照元素的值从大到小进行排序,即最大元素位于队列的前面
push(x):将元素x插入到优先队列中
pop():弹出优先队列中的顶部元素
top():返回优先队列中的顶部元素
empty():检查优先队列是否为空
size():返回优先队列中元素的个数
优先队列修改比较函数的方法
如果优先队列中的元素类型比较简单,可以直接使用greater来修改比较方法。priority_queue<int, vector,greater>pq;
std::greater内头文件中。
deque(双端队列)
deque(双端队列)是一种容器,它允许在两端进行高效的插入和删除操作。deque是由一系列连续的存储块(缓冲区)组成的,每个存储块都存储了多个元素。这使得deque能够在两端进行快速的插入和删除操作,而不需要移动其他元素。
push back(x):在尾部插入元素 x
push front(x):在头部插入元素 x
pop _back():弹出尾部元素
pop_front():弹出头部元素
front():返回头部元素
back():返回尾部元素
empty():检查 deque 是否为空
size():返回 deque 中元素的个数
clear():清空 deque 中的所有元素
pair
在C++中,pair是一个模板类,用于表示一对值的组合。它位于< utility >头文件中。pair类的定义如下:
template<class T1,class T2>
struct pair {
T1 first;//第一个值
T2 second;//第二个值
pair();
pair(const T1& x, const T2& y);
//比较运算符重载
bool operator==(const pair& rhs)const;
bool operator!=(const pair& rhs)const;
//其它成员函数和属性...
};
pair类模板有两个模板参数,T1和T2,分别表示第一个值和第二个值的类型
pair类有两个成员变量,first和second,分别表示第一个值和第二个值。
pair类还有一些成员函数和特性,例如默认构造函数、带参数的构造函数、比较运算符重载等。
使用pair类,你可以方便地将两个值组合在一起,并进行传递、存储和操作。
例如,可以将两个整数组合在一起作为返回值,或者将一对值存储在容器中。
代码示例:
#include<utility>
int main()
{
pair<int, double>p1(1, 1.5);
pair<char, string>p2('a', "hello");
cout << p1.first << " " << p1.second << " " << endl;
cout << p2.first << " " << p2.second << " " << endl;
return 0;
}
pair可以进行嵌套,也就是说可以将一个pair对象作为另一个pair对象的成员通过嵌套pair,你可以方便地组合多个值,并形成更复杂的数据结构。
例如,你可以创建一个三维坐标系的点,其中第1个维度由一个整数表示第2、3个维度由一个pair表示
int main()
{
pair<int, int> p1(1, 2);
pair<int, pair<int, int>>p2(3, make_pair(4, 5));
cout << p1.first << " " << p1.second << endl;
cout << p2.first << " " << p2.second.first << " " << p2.second.second << endl;
}
pair自带的排序规则是按照first成员进行升序排序如果first成员相等,则按照second成员进行升序排序这意味着当你使用标准库中的排序算法(如std::sort对包含pair对象的容器进行排序时会根据pair对象的first成员进行排序。
代码示例:
struct Person
{
string name;
int age;
};
int main()
{
//创建一个存储Person的数组
vector<Person>people;
//添加Person对象到数组中
people.push_back({ "Ain",25 });
people.push_back({ "Bin",15 });
people.push_back({ "Cin",45 });
//创建一个存储pair的数组,每个pair包含一个Person对象和一个评分
vector<pair<Person, int>>scores;
//添加一些pair到数组中
scores.push_back({ people[0], 90 });
scores.push_back({ people[1], 95 });
scores.push_back({ people[2], 70 });
for (const auto& pair : scores) {
cout << "Name" << pair.first.name << endl;
cout << "Age" << pair.first.age << endl;
cout << "Score" << pair.second << endl;
}
return 0;
}
set(集合)
set是一种容器,用于存储一组唯一的元素,并按照一定的排序规则进行排序。set中的元素是按照升序排序的,默认情它使用元素的比较运算符(<)来进行排序.
set的内部实现使用了红黑树(一种自平衡的二叉搜索树)来存储元素,并保持元素的有序性。这使得在set中插入、删除和查找元素的时间复杂度都是对数时间,即O(logn)。set中的元素是唯一的,即不允许重复的元素存在。当插入一个重复的元素时,set会自动忽略该元素
insert:向集合中插入元素
erase:从集合中移除元素
find:查找集合中的元素
lower_bound:返回第一个不小于给定值的选代器
upper _bound:返回第一个大于给定值的迭代器
equal_range:返回一个范围,其中包含所有给定值的元素
size:返回集合中元案的数量
empty:检查集合是否为空
clear:清空集合
begin:返回指向集合起始位置的迭代器
end:返回指向集合未尾位置的迭代器
rbegin:返回指向集合末尾位置的逆向迭代器
rend:返回指向集合起始位置的逆向迭代器
swap:交换两个集合
multiset
multiset是一种容器,它与set类似,用于存储一组元素,并按照一定的排序规则进行排序。
不同之处在于,multiset容器允许存储重复的元素。
multiset的内部实现也使用红黑树来存储元案,并保持元系的有序性。与set不同的定,multiset中的元系可以重复出现。
insert:向多重集合中插入元素
erase:从多重集合中移除元素(如果只想移除一个可以st.erase(st.find(x)))只删除一个迭代器
find:查找多重集合中的元素
lower_bound:返回第一个不小于给定值的迭代器
upper_bound:返回第一个大于给定值的迭代器
equal_range:返回一个范国,其中包含所有给定值的元案
size:返回多重集合中元素的数
empty:检查多重集合是否为空
clear:清空多重集合
begin:返回指向多重集合起始位置的迭代器
end:返回指向多重集合末尾位置的迭代器
rbegin:返回指向多重集合未尾位置的逆向迭代器
rend:返回指向多重集合起始位置的逆向迭代照
swap:交换两个多重集合
unordered_set
unordered_set是一种容器,用于存储一组唯一的元素,并且没有特定的顺序。unordered_set容器使用哈希表来实现元素的存储和访问,因此元素的插入、删除和查找的时间复杂度都是常数时间,平均复杂度O(1)。
insert:向无序集合中插入元素
erase:从无序集合中移除元素
find:查找无序集合中的元素
count:返回元素在集合中的出现次数
size:返回无序集合中元素的数量
平均时间复杂度都为O(1),最坏时间复杂度都为O(n)
这些时间复杂度是基于哈希函数的性能和哈希冲突的情况来计算的。平均情况下,unorderedset的插入、查找和移余操作都具有常数时间复杂度O(1)。然而,在最坏情况下,这些操作的时间复杂度可能为O(n),其中n是无序集合中的元素数量。最坏情况通常发生在哈希冲突较为严重的情况导致需要线性探测或链式解决冲突,从而影响性能。沂以我们一般情况下不会使用unorderedset,而选择使用复杂度更稳定的set。
代码示例
#include<set>
int main()
{
set<int>mySet;
//set<int, greater<int>>mySet;
mySet.insert(5);
mySet.insert(1);
mySet.insert(6);
mySet.insert(8);
mySet.insert(2);
for (const auto& i : mySet)
{
cout << i << ' ';
}
cout << endl;
//查找元素
int v = 5;
auto it = mySet.find(v);
if (it != mySet.end())
{
cout << v << "找到啦" << endl;
}
else
{
cout << "没找到" << endl;
}
//移除元素
int rm = 2;
mySet.erase(rm);
for (const auto& i : mySet)
{
cout << i << ' ';
}
cout << endl;
//清空
mySet.clear();
//检查是否为空
if (mySet.empty())
{
cout << "是空的" << endl;
}
else
{
cout << "不是空的" << endl;
}
return 0;
}
map
map是一种关联容器,用于存储一组键值对(key-value pairs),其中每个键(key)都是唯一的。
map容器根据键来自动进行排序,并且可以通过键快速查找对应的值。
map容器使用红黑树(Red-Black Tree)数据结构来实现,具有较快的插入、删除和査找操作的时间复杂度O(logn)。
insert:插入元素
erase:删除元素
find:查找元素
count:统计元素个数(判断key是否存在,有多少个键值对是以当前这个元素为键的)
size:返回元素个数
begin:返回指向容器起始位置的迭代器
end:返回指向容器末尾位置的迭代器
clear:清空容器
empty:判断容器是否为空
lower bound:返回指向第一个不小于指定键的元素位置
upper_bound:返回指向第一个大于指定键的元素位置
multimap
multimap是一种关联容器,类似于map,但允许存储多个具有相同键的键值对。multimap容器根据键来自动进行排序,并且可以通过键快速查找对应的值。mu1timap容器使用红黑树(Red-Black Tree)数据结构来实现,具有较快的插入、删除和査找操作
insert:插入元素
erase:删除元素
find:查找元素
count:统计元素个数
size:返回元素个数
begin:返回指向容器起始位置的迭代器
end:返回指向容器末尾位置的迭代器
clear:清空容器
empty:判断容器是否为空
unordered_map
unordered_map是一种关联容器,用于存储一组键值对(key-value pairs)其中錘个键(key)都是唯一的。
与map和multimap不同,unordered_mp不会根据键的顺序进行排序,而是使用哈希函数将键映射到存储桶中。
这使得unordered_map(平均)具有更快的插入、删除和查找操作的时间复杂度,但不保证元素的顺序。
insert:插入元素
erase:删除元素
find:查找元素
count:计数指定键的元素个数
size:返回元素个数
empty:判断容器是否为空
clear:清空容器
代码示例:
#include <map>
int main() {
// 定义一个 map,键为 string 类型,值为 int 类型
map<string, int> myMap;
// 插入元素
myMap["apple"] = 3;
myMap["banana"] = 5;
myMap["orange"] = 2;
// 使用 insert 函数插入元素
myMap.insert(make_pair("grape", 4));
// 查找元素
string key = "banana";
if (myMap.find(key) != myMap.end()) {
cout << key << " found with value: " << myMap[key] << endl;
}
else {
cout << key << " not found" << endl;
}
// 遍历 map
cout << "All elements in the map:" << endl;
for (const auto& pair : myMap) {
cout << pair.first << " => " << pair.second << endl;
}
// 删除元素
myMap.erase("orange");
// 再次遍历 map,查看删除后的结果
cout << "After erasing 'orange':" << endl;
for (const auto& pair : myMap) {
cout << pair.first << " => " << pair.second << endl;
}
return 0;
}