c++map与set

1.set

set的底层结构是红黑树实现的,set的迭代器是双向迭代器但是由于set属于平衡二叉搜索树属于set的节点是不能修改的。set的迭代器的是中序遍历所以是有序的,set的增删查的时间复杂度是O(logN)。

1.1set的增删查

set的插入接口是insert函数,set插入时如果有重复的则会插入失败。set的删除接口是erase函数,查找是find函数返回值是set的迭代器。

复制代码
//删除
int main()
6 {
7 set<int> s = { 4,2,7,2,8,5,9 };
8 for (auto e : s)
9 {
10 cout << e << " ";
11 }
12 cout << endl;
13
14 // 删除最⼩值
15 s.erase(s.begin());
16 for (auto e : s)
17 {
18 cout << e << " ";
19 }
20 cout << endl;
21
22 // 直接删除x
23 int x;
24 cin >> x;
25 int num = s.erase(x);
26 if (num == 0)
27 {
28 cout << x << "不存在!" << endl;
29 }
30
31 for (auto e : s)
32 {
33 cout << e << " ";
34 }
35 cout << endl;
36
37 // 直接查找在利⽤迭代器删除x
38 cin >> x;
39 auto pos = s.find(x);
40 if (pos != s.end())
41 {
42 s.erase(pos);
43 }
44 else
45 {
46 cout << x << "不存在!" << endl;
47 }
48
49 for (auto e : s)
50 {
51 cout << e << " ";
52 }
53 cout << endl;
54
55 // 算法库的查找 O(N)
56 auto pos1 = find(s.begin(), s.end(), x);
57 // set⾃⾝实现的查找 O(logN)
58 auto pos2 = s.find(x);
59
60 // 利⽤count间接实现快速查找
61 cin >> x;
62 if (s.count(x))
63 {
64 cout << x << "在!" << endl;
65 }
66 else
67 {
68 cout << x << "不存在!" << endl;
69 }
70
71 return 0;
72 }

1.2multiset与set

multi与set的区别就是是否支持重复的区别。

复制代码
#include<iostream>
2 #include<set>
3 using namespace std;
4
5 int main()
6 {
7 // 相⽐set不同的是,multiset是排序,但是不去重
8 multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };
9 auto it = s.begin();
10 while (it != s.end())
11 {
12 cout << *it << " ";
13 ++it;
14 }
15 cout << endl;
16
17 // 相⽐set不同的是,x可能会存在多个,find查找中序的第⼀个
18 int x;
19 cin >> x;
20 auto pos = s.find(x);
21 while (pos != s.end() && *pos == x)
22 {
23 cout << *pos << " ";
24 ++pos;
25 }
26 cout << endl;
27
28 // 相⽐set不同的是,count会返回x的实际个数
29 cout << s.count(x) << endl;
30
31 // 相⽐set不同的是,erase给值时会删除所有的x
32 s.erase(x);
33 for (auto e : s)
34 {
35 cout << e << " ";
36 }
37 cout << endl;
38
39 return 0;
40 }

2.map

map的底层结构也是红黑树,它的增删查的效率也是O(logn)。map默认升序排序的,它的迭代器走的也是中序所以也是有序的。map的迭代器也同样是不支持修改的,因为map实现的是K,value结构的每个k对应一个value,value的数据可以修改。同样value的值也是可以重复的,只不过对应的k是不能重复的。

2.1map的增删查

map的插入是插入的键值对的数据,删除和查找则是通过k跟set一样。

cpp 复制代码
1 Member types
2 key_type -> The first template parameter (Key)
3 mapped_type -> The second template parameter (T)
4 value_type -> pair<const key_type,mapped_type>
5
6 // 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
7 pair<iterator,bool> insert (const value_type& val);
8 // 列表插⼊,已经在容器中存在的值不会插⼊
9 void insert (initializer_list<value_type> il);
10 // 迭代器区间插⼊,已经在容器中存在的值不会插⼊
11 template <class InputIterator>
12 void insert (InputIterator first, InputIterator last);
13
14 // 查找k,返回k所在的迭代器,没有找到返回end()
15 iterator find (const key_type& k);
16 // 查找k,返回k的个数
17 size_type count (const key_type& k) const;
18
19 // 删除⼀个迭代器位置的值
20 iterator erase (const_iterator position);
21 // 删除k,k存在返回0,存在返回1
22 size_type erase (const key_type& k);
23 // 删除⼀段迭代器区间的值
24 iterator erase (const_iterator first, const_iterator last);
// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);
// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;

2.2map的迭代器和[]的功能

map重载了运算符[]所以map也可以像数组一样来访问数据,只不过map的[]里要所以k来查找,如果树内没有对应的k就插入。[]的返回值是value的引用所以可以通过[]来改变value的值。

cpp 复制代码
1 #include<iostream>
2 #include<map>
3 #include<string>
4 using namespace std;
5
6 int main()
7 {
8 // 利⽤find和iterator修改功能,统计⽔果出现的次数
9 string arr[] = { "苹果", "西⽠", "苹果", "西⽠", "苹果", "苹果", "西⽠",
"苹果", "⾹蕉", "苹果", "⾹蕉" };
10 map<string, int> countMap;
11 for (const auto& str : arr)
12 {
13 // 先查找⽔果在不在map中
14 // 1、不在,说明⽔果第⼀次出现,则插⼊{⽔果, 1}
15 // 2、在,则查找到的节点中⽔果对应的次数++
16 auto ret = countMap.find(str);
17 if (ret == countMap.end())
18 {
19 countMap.insert({ str, 1 });
20 }
21 else
22 {
23 ret->second++;
24 }
25 }
26
27 for (const auto& e : countMap)
28 {
29 cout << e.first << ":" << e.second << endl;
30 }
31 cout << endl;
32
33 return 0;
34 }
35
36 #include<iostream>
37 #include<map>
38 #include<string>
39 using namespace std;
40
41 int main()
42 {
43 // 利⽤[]插⼊+修改功能,巧妙实现统计⽔果出现的次数
44 string arr[] = { "苹果", "西⽠", "苹果", "西⽠", "苹果", "苹果", "西⽠",
"苹果", "⾹蕉", "苹果", "⾹蕉" };
45 map<string, int> countMap;
46 for (const auto& str : arr)
47 {
48 // []先查找⽔果在不在map中
49 // 1、不在,说明⽔果第⼀次出现,则插⼊{⽔果, 0},同时返回次数的引⽤,
++⼀下就变成1次了
50 // 2、在,则返回⽔果对应的次数++
51 countMap[str]++;
52 }
53
54 for (const auto& e : countMap)
55 {
56 cout << e.first << ":" << e.second << endl;
57 }
58 cout << endl;
59
60 return 0;
61 }
62

2.3multimap与map

multimap与map的主要区别还是是否支持k冗余,因为multimap有多个k值所以find返回的就是中序的第一个k。因为multimap支持k冗余所以没有[],因为如果重载[]也只能插入不能修改。

相关推荐
寻寻觅觅☆6 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
fpcc6 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
2013编程爱好者7 小时前
【C++】树的基础
数据结构·二叉树··二叉树的遍历
NEXT067 小时前
二叉搜索树(BST)
前端·数据结构·面试
化学在逃硬闯CS7 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar1237 小时前
C++使用format
开发语言·c++·算法
lanhuazui108 小时前
C++ 中什么时候用::(作用域解析运算符)
c++
charlee448 小时前
从零实现一个生产级 RAG 语义搜索系统:C++ + ONNX + FAISS 实战
c++·faiss·onnx·rag·语义搜索
老约家的可汗8 小时前
初识C++
开发语言·c++
crescent_悦8 小时前
C++:Product of Polynomials
开发语言·c++