1. set
特性:①唯一性:set中不允许重复的元素,每个元素在集合中是唯一的;
②有序性:set中的元素按照严格递增顺序排列;
③动态增长:set是动态增长的,可以根据需要动态地增长或减少元素的数量;
④基于红黑树实现:set通常基于红黑树(Red-Black Tree)实现,这种数据结构保证了元素的快速查找和插入操作的时间复杂度为对数时间。
函数 | 语法 | 作用 |
begin | iterator begin(); | 返回指向当前集合中第一个元素的迭代器 |
end | const_iterator end(); | 返回指向当前集合中最后一个元素的迭代器 |
clear | void clear(); | 清除当前集合中的所有元素 |
erase | 1. void erase(iterator i); 2. void erase(iterator start, iterator end); 3. size_type erase(const key_type &key); | 1. 删除元素i 2. 删除从start开始到end(不包括end)结束的元素 3. 删除等于key值的所有元素,返回被删除元素的个数 |
count | size_type count(const key_type &key); | 返回当前集合中出现的某个值的元素的数目 |
empty | bool empty(); | 如果当前集合为空,返回true;否则返回false |
find | iterator find(const key_type &key); | 在当前集合中查找等于key值的元素,并返回指向该元素的迭代器 |
size | size_type size(); | 返回当前集合中元素的数目 |
max_size | size_type max_size(); | 返回当前集合能容纳元素的最大限值 |
insert | 1. iterator insert(iterator i, const TYPE &val); 2. void insert(input_iterator start, input_iterator end); 3. pair insert(const TYPE &val); | 1. 在迭代器i前插入val 2. 将迭代器start开始到end结束范围内的元素插入到集合中 3. 在当前集合中插入val元素,并返回指向该元素的迭代器和是否插入成功的布尔值(在集合set中不能插入两个相同的元素) |
emplace | pair emplace(const TYPE &val); | 构建并将一个元素插入到集合中,并返回指向该元素的迭代器和是否插入成功的布尔值(在集合set中不能插入两个相同的元素) |
equal_range | pair equal_range(const key_type &key); | 返回集合中与给定值相等的上下限的两个迭代器 |
rbegin | reverse_iterator rbegin(); | 返回指向当前集合中最后一个元素的反向迭代器 |
rend | reverse_iterator rend(); | 返回指向集合中第一个元素的反向迭代器 |
lower_bound | iterator lower_bound(const key_type &key); | 返回一个指向大于或者等于key值的第一个元素的迭代器 |
upper_bound | iterator upper_bound(const key_type &key); | 在当前集合中返回一个指向大于key值的元素的迭代器 |
swap | void swap(set &object); | 交换当前集合和object集合中的元素 |
value_comp | value_compare value_comp(); | 返回一个用于比较元素间的值的函数对象 |
key_comp | key_compare key_comp(); | 返回一个用于元素间值比较的函数对象 |
get_allocator | allocator_type get_allocator(); | 返回当前集合的分配器 |
示例:
#include<iostream>
#include<set>
using namespace std;
int main() {
// 定义set
set<int> mySet;
// 当前集合set能容纳的最大限值,1717986918
int size = mySet.max_size();
cout << size << endl;
// 判断set是否为空
bool isEmpty = mySet.empty(); // true
cout << boolalpha << isEmpty << endl;
// 向set中插入元素
mySet.insert(1);
mySet.insert(2);
mySet.insert(3);
mySet.insert(5);
mySet.emplace(4); // 向set中插入元素
pair<set<int>::iterator, bool> result = mySet.insert(1); // 唯一性
cout << boolalpha << result.second << endl; // false,表示插入失败
// 遍历set中的元素
for(set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) { // 1 2 3 4 5(有序性)
cout << *it << " ";
}
cout << endl;
// 统计set中值为1的元素的数目
int count = mySet.count(1);
cout << count << endl; // 1
// 在set中查找等于3的元素,并返回指向该元素的迭代器
set<int>::iterator it = mySet.find(3);
if(it != mySet.end()) {
cout << "Element 3 found in the set" << endl; // √
} else {
cout << "Element 3 not found in the set" << endl;
}
// 返回大于等于2的第一个元素的迭代器
set<int>::iterator it2 = mySet.lower_bound(2);
cout << *it2 << endl; // 2
// 返回大于2的第一个元素的迭代器
set<int>::iterator it3 = mySet.upper_bound(2);
cout << *it3 << endl; // 3
// 删除从it2到it3的元素(不包括it3)
mySet.erase(it2, it3);
for(set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) { // 1 3 4 5
cout << *it << " ";
}
cout << endl;
// 清除set中的所有元素
mySet.clear();
cout << boolalpha << mySet.empty(); // true
return 0;
}
2. unordered_set
set | unordered_set | |
有序性 | 元素按照严格递增顺序排列 | 元素是无序的 |
唯一性 | 元素不允许重复 | 元素不允许重复 |
底层数据结构 | 通常基于红黑树实现,在插入、删除和查找操作的时间复杂度为对数时间 | 通常基于哈希表实现,在插入、删除和查找操作的时间复杂度为常数时间 |
迭代器顺序 | 迭代器会按照元素的顺序进行遍历 | 迭代器遍历顺序是不固定的,取决于哈希表中元素的存储情况 |
#include<iostream>
#include<set>
#include<unordered_set>
using namespace std;
int main() {
set<int> set1 = {2, 1, 4, 3, 2};
// 有序性:递增 && 元素唯一性
for(set<int>::iterator it = set1.begin(); it != set1.end(); ++it) { // 1 2 3 4
cout << *it << " ";
}
cout << endl;
unordered_set<int> set2 = {2, 1, 4, 3, 2};
// 无序性 && 元素唯一性
for(unordered_set<int>::iterator it = set2.begin(); it != set2.end(); ++it) { // 3 4 1 2
cout << *it << " ";
}
cout << endl;
return 0;
}
3. map
特性:①有序性:map中的元素是按照键的大小进行排序的,默认按照键的升序排列;
②键值对:map中存储的是键值对,每一个键都与一个值相关联。键是唯一的,值可以重复;
③基于红黑树实现:map通常基于红黑树(一种非严格意义是平衡二叉树)实现,保证了插入、删除和查找操作的平均时间复杂度为对数时间;
函数 | 语法 | 作用 |
begin | iterator begin(); | 返回一个迭代器指向map的第一个元素 |
end | iterator end(); | 返回一个迭代器指向map的尾部 |
find | iterator find(const KEY_TYPE &key); | 返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器 |
insert | 1. iterator insert(iterator pos, const pair<KEY_TYPE, VALUE_TYPE> &val); 2. void insert(input_iterator start, input_iterator end); 3. pair<iterator, bool> insert(const pair<KEY_TYPE, VALUE_TYPE> &val); | 1. 插入val到pos的后面,然后返回一个指向这个元素的迭代器 2. 插入从start到end的元素到map中 3. 只有在val不存在时插入val。返回值是一个指向被插入元素的迭代器和一个描述是否插入的bool值 |
erase | 1. void erase(iterator pos); 2. void erase(iterator start, iterator end); 3. size_type erase(const KEY_TYPE &key); | 1. 删除在pos位置的元素 2. 删除在start和end之间的元素 3. 删除值为key的元素 |
clear | void clear(); | 删除map中的所有元素 |
size | size_type size(); | 返回map中保存的元素个数 |
max_size | size_type max_size(); | 返回map能够保存的最大元素个数 |
count | size_type count(const KEY_TYPE &key); | 返回map中键值等于key的元素的个数 |
lower_bound | iterator lower_bound(const KEY_TYPE &key); | 返回一个迭代器,指向map中键值大于或等于key的第一个元素 |
upper_bound | iterator upper_bound(const KEY_TYPE &key); | 返回一个迭代器,指向map中键值大于key的第一个元素 |
empty | bool empty(); | 如果map为空返回true,否则返回false |
rbegin | reverse_iterator rbegin(); | 返回一个指向map尾部的逆向迭代器 |
rend | reverse_iterator rend(); | 返回一个指向map头部的逆向迭代器 |
equal_range | pair equal_range(const KEY_TYPE &key); | 返回两个迭代器:一个指向第一个键值为key的元素,另一个指向最后一个键值为key的元素 |
get_allocator | allocator_type get_allocator(); | 返回map的配置器 |
key_comp | key_compare key_comp(); | 返回一个比较key的函数 |
swap | void swap(map &obj); | 交换obj和现map中的元素 |
value_comp | value_compare value_comp(); | 返回一个比较元素value的函数 |
#include<iostream>
#include<map>
using namespace std;
int main() {
// key->value
// 初始化map
map<int, string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
// 插入元素
myMap.insert(make_pair(4, "four")); // 使用insert插入
myMap.emplace(5, "five"); // 使用emplace插入
myMap.emplace(2, "second"); // map中key不可以重复,value可以重复
myMap.emplace(6, "five");
// 访问元素
for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}
/*
1 : one
2 : two
3 : three
4 : four
5 : five
6 : five
*/
cout << endl;
// 删除元素
myMap.erase(1); // key
for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); ++it) { //
cout << it->first << " : " << it->second << endl;
}
/*
2 : two
3 : three
4 : four
5 : five
6 : five
*/
cout << endl;
// 查找元素
auto it = myMap.find(2);
if(it != myMap.end()) {
cout << "元素存在" <<endl; // √
} else {
cout << "元素不存在" << endl;
}
// 获取元素个数
int size = myMap.size();
cout << size <<endl; // 5
// 清空map
myMap.clear();
cout << myMap.size() << endl; // 0
return 0;
}
4. unordered_map
map | unordered_map | |
底层实现 | 基于红黑树实现,保持元素有序,插入、删除、查找操作的时间复杂度为O(logn) | 基于哈希表实现,元素无序存储,插入、删除、查找操作的平均时间复杂度为O(1),最坏情况下为O(n) |
有序性 | 元素按小键的大升序排列,支持自定义排序规则 | 元素无序存储,不支持自定义排序规则 |
唯一性 | 键key的值不可以重复,value值可以重复 | 键key的值不可以重复,value值可以重复 |
性能 | 适用于需要元素有序存储且需要快速查找、插入、删除的场景,对于有序性要求高的情况较为适用 | 适用于查找操作性能要求较高的场景,由于使用哈希表实现,查找速度通常比map快 |
内存占用 | 由于使用红黑树实现,占用的内存空间较大 | 由于使用哈希表实现,通常占用的内存空间较小 |
#include<iostream>
#include<map>
#include<unordered_map>
using namespace std;
int main() {
// 初始化map
map<int, string> orderedMap = {{3, "three"}, {1, "one"}, {2, "two"}};
// 遍历map
for(map<int, string>::iterator it = orderedMap.begin(); it != orderedMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}
/*
1 : one
2 : two
3 : three
*/
cout << endl;
// 初始化unordered_map
unordered_map<int, string> unorderedMap = {{3, "three"}, {1, "one"}, {2, "two"}};
// 遍历unordered_map
for(unordered_map<int, string>::iterator it = unorderedMap.begin(); it != unorderedMap.end(); ++it) {
cout << it->first << " : " << it->second << endl;
}
/*
2 : two
3 : three
1 : one
*/
cout << endl;
return 0;
}