STL之set容器和multiset容器

柔情只为你懂 2023-10-11 13:28 112阅读 0赞

摘要:本文主要介绍了set容器和multiset容器的相关内容。

1、基本概念


















  set容器 multiset容器
概念

所有元素都会根据元素的键值自动被排序,

元素即是键值又是实值,不允许两个元素

有相同的键值,元素值不可以被改变

multiset特性及用法和set完全相同,

唯一的差别在于它允许键值重复

实现

set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种

2、二叉树

2.1 概念

二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点。

1510791-20190821202718844-744261107.jpg

2.2 二叉搜索树

1510791-20190821202824883-1645944449.png

上面我们介绍了二叉搜索树,那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索9所花费的时间要比搜索17所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。

所以我们有了一个平衡二叉树的概念,所谓的平衡不是指的完全平衡。

1510791-20190821202940119-1011022328.png

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) 返回容器中keykeyElem相等的上下限的两个迭代器

4、对组

对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用pair的两个公有属性first和second访问。

类模板:template struct pair.创建对组的方式如下:
















第一种方法创建一个对组

pair<stringint> pair1(string(“name”), 20);

cout << pair1.first << endl; //访问pair第一个值

cout << pair1.second << endl;//访问pair第二个值

第二种方法创建一个对组

pair<stringint> pair2 = make_pair(“name”, 30);

       cout << pair2.first << endl;

      cout << pair2.second << endl;

第二种方法pair=赋值

     pair<stringint> pair3 = pair2;

       cout << pair3.first << endl;

      cout << pair3.second << endl;

5、代码示例

  1. 1 #include<iostream>
  2. 2 #include <set>
  3. 3 #include <string>
  4. 4
  5. 5 using namespace std;
  6. 6
  7. 7 void printSet(set<int>&s) {
  8. 8 for (set<int>::iterator it = s.begin(); it != s.end();it++) {
  9. 9 cout << *it << " ";
  10. 10 }
  11. 11 cout << endl;
  12. 12 }
  13. 13
  14. 14 void test01() { //定义容器、插入数据、判断是否为空,删除数据
  15. 15 set<int>s;
  16. 16 s.insert(10); //set容器会自动将添加的数据进行排列,只能用insert
  17. 17 s.insert(8);
  18. 18 s.insert(11);
  19. 19 s.insert(19);
  20. 20 s.insert(2);
  21. 21 printSet(s);
  22. 22
  23. 23 if (s.empty()) //测试是否为空
  24. 24 {
  25. 25 cout << "容器为空" << endl;
  26. 26 }
  27. 27 else {
  28. 28 cout << "容器不为空,且大小为:" <<s.size()<< endl;
  29. 29 }
  30. 30
  31. 31 s.erase(s.begin()); //指明删除数据的位置
  32. 32 printSet(s);
  33. 33 s.erase(11); //指明具体要删除的数据值
  34. 34 printSet(s);
  35. 35 }
  36. 36
  37. 37 void test02(){ //进行数据查找
  38. 38 set<int>s;
  39. 39 s.insert(10);
  40. 40 s.insert(8);
  41. 41 s.insert(11);
  42. 42 s.insert(19);
  43. 43 s.insert(2);
  44. 44
  45. 45 set<int>::iterator pos = s.find(2); //类函数find返回值是迭代器
  46. 46 if (pos!=s.end()) {
  47. 47 cout << "数据存在,值为:" << *pos << endl;
  48. 48 }
  49. 49 else {
  50. 50 cout << "数据不存在" << endl;
  51. 51 }
  52. 52
  53. 53 int num = s.count(2);
  54. 54 cout << num << endl; //输出相应的元素的个数,在set中,只有0和1
  55. 55
  56. 56 //lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器
  57. 57 set<int>::iterator it = s.lower_bound(10);
  58. 58 if (it != s.end())
  59. 59 {
  60. 60 cout << "找到了 lower_bound (10)的值为:" << *it << endl;
  61. 61 }
  62. 62 else
  63. 63 {
  64. 64 cout << "未找到" << endl;
  65. 65 }
  66. 66 // upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
  67. 67 set<int>::iterator it2 = s.upper_bound(10);
  68. 68 if (it2 != s.end())
  69. 69 {
  70. 70 cout << "找到了 upper_bound (10)的值为:" << *it2 << endl;
  71. 71 }
  72. 72 else
  73. 73 {
  74. 74 cout << "未找到" << endl;
  75. 75 }
  76. 76 //equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
  77. 77 //上下限 就是lower_bound upper_bound
  78. 78 //注意这里用到了对组
  79. 79 pair<set<int>::iterator, set<int>::iterator> ret = s.equal_range(10);
  80. 80 if (ret.first != s.end()) //第一个值
  81. 81 {
  82. 82 cout << "找到equal_range中 lower_bound 的值 :" << *(ret.first) << endl;
  83. 83 }
  84. 84 else
  85. 85 {
  86. 86 cout << "未找到" << endl;
  87. 87 }
  88. 88 if (ret.second != s.end()) //第二个值
  89. 89 {
  90. 90 cout << "找到equal_range中 upper_bound 的值 :" << *(ret.second) << endl;
  91. 91 }
  92. 92 else
  93. 93 {
  94. 94 cout << "未找到" << endl;
  95. 95 }
  96. 96 }
  97. 97
  98. 98 void test03() { //证明set容器不可以重复插入某一个键值
  99. 99 set<int>s;
  100. 100 pair<set<int>::iterator, bool>ret = s.insert(10); //第二个bool值可以反映是否插入成功
  101. 101 if (ret.second)
  102. 102 {
  103. 103 cout << "插入成功" << endl;
  104. 104 }
  105. 105 else {
  106. 106 cout << "插入失败" << endl;
  107. 107 }
  108. 108 ret = s.insert(10);
  109. 109 if (ret.second)
  110. 110 {
  111. 111 cout << "第二次插入成功" << endl;
  112. 112 }
  113. 113 else
  114. 114 {
  115. 115 cout << "第二次插入失败" << endl;
  116. 116 }
  117. 117 printSet(s);
  118. 118
  119. 119 //multiset允许插入重复值
  120. 120 multiset<int> mul;
  121. 121 mul.insert(10);
  122. 122 mul.insert(10);
  123. 123 }
  124. 124
  125. 125 //指定set排序规则 从大到小
  126. 126 //仿函数
  127. 127 class myCompare
  128. 128 {
  129. 129 public:
  130. 130 //重载 ()
  131. 131 bool operator()(int v1, int v2)
  132. 132 {
  133. 133 return v1 > v2;
  134. 134 }
  135. 135 };
  136. 136 //set容器的排序
  137. 137 void test04()
  138. 138 {
  139. 139 set<int, myCompare>s1;
  140. 140
  141. 141 s1.insert(5);
  142. 142 s1.insert(1);
  143. 143 s1.insert(9);
  144. 144 s1.insert(3);
  145. 145 s1.insert(7);
  146. 146
  147. 147 //printSet(s1);
  148. 148
  149. 149 //从大到小排序
  150. 150 //在插入之前就指定排序规则
  151. 151
  152. 152 for (set<int, myCompare>::iterator it = s1.begin(); it != s1.end(); it++)
  153. 153 {
  154. 154 cout << *it << " ";
  155. 155 }
  156. 156 cout << endl;
  157. 157 }
  158. 158
  159. 159 //自定义数据类型
  160. 160 class Person
  161. 161 {
  162. 162 public:
  163. 163 Person(string name, int age)
  164. 164 {
  165. 165 this->m_Name = name;
  166. 166 this->m_Age = age;
  167. 167 }
  168. 168
  169. 169 string m_Name;
  170. 170 int m_Age;
  171. 171 };
  172. 172
  173. 173 class myComparePerson
  174. 174 {
  175. 175 public:
  176. 176 bool operator()(const Person & p1, const Person & p2)
  177. 177 {
  178. 178 if (p1.m_Age > p2.m_Age) //降序
  179. 179 {
  180. 180 return true;
  181. 181 }
  182. 182 return false;
  183. 183 }
  184. 184
  185. 185 };
  186. 186
  187. 187 void test05()
  188. 188 {
  189. 189 set<Person, myComparePerson> s1;
  190. 190
  191. 191 Person p1("大娃", 100);
  192. 192 Person p2("二娃", 90);
  193. 193 Person p3("六娃", 10);
  194. 194 Person p4("爷爷", 1000);
  195. 195
  196. 196 s1.insert(p1);
  197. 197 s1.insert(p2);
  198. 198 s1.insert(p3);
  199. 199 s1.insert(p4);
  200. 200
  201. 201 //插入自定义数据类型,上来就指定好排序规则
  202. 202
  203. 203 //显示
  204. 204 for (set<Person, myComparePerson>::iterator it = s1.begin(); it != s1.end(); it++)
  205. 205 {
  206. 206 cout << "姓名:" << (*it).m_Name << " 年龄: " << it->m_Age << endl;
  207. 207 }
  208. 208
  209. 209 }
  210. 210
  211. 211 int main() {
  212. 212 //test01();
  213. 213 //test02();
  214. 214 //test03();
  215. 215 //test04();
  216. 216 test05();
  217. 217 system("pause");
  218. 218 return 0;
  219. 219 }

转载于:https://www.cnblogs.com/lzy820260594/p/11391260.html

发表评论

表情:
评论列表 (有 0 条评论,112人围观)

还没有评论,来说两句吧...

相关阅读