STL之set容器和multiset容器
摘要:本文主要介绍了set容器和multiset容器的相关内容。
1、基本概念
set容器 | multiset容器 | |
概念 | 所有元素都会根据元素的键值自动被排序, 元素即是键值又是实值,不允许两个元素 有相同的键值,元素值不可以被改变 | multiset特性及用法和set完全相同, 唯一的差别在于它允许键值重复 |
实现 | set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种 |
2、二叉树
2.1 概念
二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点。
2.2 二叉搜索树
上面我们介绍了二叉搜索树,那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索9所花费的时间要比搜索17所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。
所以我们有了一个平衡二叉树的概念,所谓的平衡不是指的完全平衡。
RB-tree(红黑树)为二叉树的一种。
3、常用API
set | multiset | |||
API | 意义 | API | 意义 | |
构造函数 | set<T> st | set默认构造函数 | mulitset<T> mst | multiset默认构造函数 |
set(const set &st) | 拷贝构造函数 | |||
赋值操作 | set& operator=(const set &st) | 重载等号操作符 | ||
swap(st) | 交换两个集合容器 | |||
大小操作 | size() | 返回容器中元素的数目 | ||
empty() | 判断容器是否为空 | |||
插入和删除操作 | insert(elem) | 在容器中插入元素 | ||
clear() | 清除所有元素 | |||
erase(pos) | 删除pos迭代器所指的元素,返回下一个元素的迭代器 | |||
erase(beg, end) | 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器 | |||
erase(elem) | 删除容器中值为elem的元素 | |||
查找操作 | find(key) | 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end() | ||
count(key) | 查找键key的元素个数 | |||
lower_bound(keyElem) | 返回第一个key>=keyElem元素的迭代器 | |||
upper_bound(keyElem) | 返回第一个key>keyElem元素的迭代器 | |||
equal_range(keyElem) | 返回容器中key与keyElem相等的上下限的两个迭代器 |
4、对组
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有属性first和second访问。
类模板:template
第一种方法创建一个对组 | pair<string, int> pair1(string(“name”), 20); cout << pair1.first << endl; //访问pair第一个值 cout << pair1.second << endl;//访问pair第二个值 |
第二种方法创建一个对组 | pair<string, int> pair2 = make_pair(“name”, 30); cout << pair2.first << endl; cout << pair2.second << endl; |
第二种方法pair=赋值 | pair<string, int> pair3 = pair2; cout << pair3.first << endl; cout << pair3.second << endl; |
5、代码示例
1 #include<iostream>
2 #include <set>
3 #include <string>
4
5 using namespace std;
6
7 void printSet(set<int>&s) {
8 for (set<int>::iterator it = s.begin(); it != s.end();it++) {
9 cout << *it << " ";
10 }
11 cout << endl;
12 }
13
14 void test01() { //定义容器、插入数据、判断是否为空,删除数据
15 set<int>s;
16 s.insert(10); //set容器会自动将添加的数据进行排列,只能用insert
17 s.insert(8);
18 s.insert(11);
19 s.insert(19);
20 s.insert(2);
21 printSet(s);
22
23 if (s.empty()) //测试是否为空
24 {
25 cout << "容器为空" << endl;
26 }
27 else {
28 cout << "容器不为空,且大小为:" <<s.size()<< endl;
29 }
30
31 s.erase(s.begin()); //指明删除数据的位置
32 printSet(s);
33 s.erase(11); //指明具体要删除的数据值
34 printSet(s);
35 }
36
37 void test02(){ //进行数据查找
38 set<int>s;
39 s.insert(10);
40 s.insert(8);
41 s.insert(11);
42 s.insert(19);
43 s.insert(2);
44
45 set<int>::iterator pos = s.find(2); //类函数find返回值是迭代器
46 if (pos!=s.end()) {
47 cout << "数据存在,值为:" << *pos << endl;
48 }
49 else {
50 cout << "数据不存在" << endl;
51 }
52
53 int num = s.count(2);
54 cout << num << endl; //输出相应的元素的个数,在set中,只有0和1
55
56 //lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器
57 set<int>::iterator it = s.lower_bound(10);
58 if (it != s.end())
59 {
60 cout << "找到了 lower_bound (10)的值为:" << *it << endl;
61 }
62 else
63 {
64 cout << "未找到" << endl;
65 }
66 // upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
67 set<int>::iterator it2 = s.upper_bound(10);
68 if (it2 != s.end())
69 {
70 cout << "找到了 upper_bound (10)的值为:" << *it2 << endl;
71 }
72 else
73 {
74 cout << "未找到" << endl;
75 }
76 //equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
77 //上下限 就是lower_bound upper_bound
78 //注意这里用到了对组
79 pair<set<int>::iterator, set<int>::iterator> ret = s.equal_range(10);
80 if (ret.first != s.end()) //第一个值
81 {
82 cout << "找到equal_range中 lower_bound 的值 :" << *(ret.first) << endl;
83 }
84 else
85 {
86 cout << "未找到" << endl;
87 }
88 if (ret.second != s.end()) //第二个值
89 {
90 cout << "找到equal_range中 upper_bound 的值 :" << *(ret.second) << endl;
91 }
92 else
93 {
94 cout << "未找到" << endl;
95 }
96 }
97
98 void test03() { //证明set容器不可以重复插入某一个键值
99 set<int>s;
100 pair<set<int>::iterator, bool>ret = s.insert(10); //第二个bool值可以反映是否插入成功
101 if (ret.second)
102 {
103 cout << "插入成功" << endl;
104 }
105 else {
106 cout << "插入失败" << endl;
107 }
108 ret = s.insert(10);
109 if (ret.second)
110 {
111 cout << "第二次插入成功" << endl;
112 }
113 else
114 {
115 cout << "第二次插入失败" << endl;
116 }
117 printSet(s);
118
119 //multiset允许插入重复值
120 multiset<int> mul;
121 mul.insert(10);
122 mul.insert(10);
123 }
124
125 //指定set排序规则 从大到小
126 //仿函数
127 class myCompare
128 {
129 public:
130 //重载 ()
131 bool operator()(int v1, int v2)
132 {
133 return v1 > v2;
134 }
135 };
136 //set容器的排序
137 void test04()
138 {
139 set<int, myCompare>s1;
140
141 s1.insert(5);
142 s1.insert(1);
143 s1.insert(9);
144 s1.insert(3);
145 s1.insert(7);
146
147 //printSet(s1);
148
149 //从大到小排序
150 //在插入之前就指定排序规则
151
152 for (set<int, myCompare>::iterator it = s1.begin(); it != s1.end(); it++)
153 {
154 cout << *it << " ";
155 }
156 cout << endl;
157 }
158
159 //自定义数据类型
160 class Person
161 {
162 public:
163 Person(string name, int age)
164 {
165 this->m_Name = name;
166 this->m_Age = age;
167 }
168
169 string m_Name;
170 int m_Age;
171 };
172
173 class myComparePerson
174 {
175 public:
176 bool operator()(const Person & p1, const Person & p2)
177 {
178 if (p1.m_Age > p2.m_Age) //降序
179 {
180 return true;
181 }
182 return false;
183 }
184
185 };
186
187 void test05()
188 {
189 set<Person, myComparePerson> s1;
190
191 Person p1("大娃", 100);
192 Person p2("二娃", 90);
193 Person p3("六娃", 10);
194 Person p4("爷爷", 1000);
195
196 s1.insert(p1);
197 s1.insert(p2);
198 s1.insert(p3);
199 s1.insert(p4);
200
201 //插入自定义数据类型,上来就指定好排序规则
202
203 //显示
204 for (set<Person, myComparePerson>::iterator it = s1.begin(); it != s1.end(); it++)
205 {
206 cout << "姓名:" << (*it).m_Name << " 年龄: " << it->m_Age << endl;
207 }
208
209 }
210
211 int main() {
212 //test01();
213 //test02();
214 //test03();
215 //test04();
216 test05();
217 system("pause");
218 return 0;
219 }
转载于//www.cnblogs.com/lzy820260594/p/11391260.html
还没有评论,来说两句吧...