STL——容器(Set & multiset)的概念和特点
1. Set 和 multiset 的概念
set 和 multiset 是一个集合容器,其中 set 所包含的元素是唯一的,集合中的元素按一定的顺序排列。set 采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比 vector 快。在n个数中查找目标数的效率是 log2N(2的多少次方等于N,这个效率非常之高,从16个单位中查找需要4次,64个单位需要6次……4,294,967,296个单位只需要32次)
红黑树定义是每个节点都带有颜色属性(颜色为红色或黑色)的自平衡二叉查找树,满足下列性质:
1)节点是红色或黑色;
2)根节点是黑色;
3)所有叶子节点都是黑色节点(NULL);
4)每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
5)从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
2. Set 和 multiset 特点
1. set 中元素插入过程是按排序规则插入,所以不能指定插入位置(不能打破红黑树的位置结构)。
2. set 不可以直接存取元素,不可以使用 at.(pos) 和 [ ] 操作符。
3. multiset 与 set 的区别:set支持唯一键值,每个元素值只能出现一次;而 multiset 中同一值可以出现多次。
4. 不可以直接修改 set 或 multiset 容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素
5. 头文件 #include <set>
3. set 的使用举例
1 #include <iostream> 2 #include <set> 3 4 using namespace std; 5 6 int main() 7 { 8 set<int> setInt; 9 10 for (int i = 0; i < 10; i++) 11 { 12 setInt.insert(100 - i); //插入顺序为 100 99 98 97 96 95 94 93 92 91 13 } 14 15 setInt.insert(99); //再插入一个 99 16 17 for (set<int>::iterator it = setInt.begin(); it != setInt.end(); it++) 18 { 19 cout << *it << " "; //遍历后会发现不管你先插入多少,set 中已将数据从小到大排列,并且只有1个 99 20 } 21 22 cout << endl; 23 24 return 0; 25 }
打印结果中可以看到容器中的数据已经从小到大排列,并且中间再次插入的 99 不存在:
接下来使用一下 multiset,multiset 允许同一个元素多次存在:
1 #include <iostream> 2 #include <set> 3 4 using namespace std; 5 6 int main() 7 { 8 multiset<int> msetInt; 9 10 for (int i = 0; i < 10; i++) 11 { 12 msetInt.insert(100 - i); //插入顺序为 100 99 98 97 96 95 94 93 92 91 13 } 14 15 msetInt.insert(99); //再插入一个 99 16 17 for (set<int>::iterator it = msetInt.begin(); it != msetInt.end(); it++) 18 { 19 cout << *it << " "; //遍历后会发现不管你先插入多少,set 中已将数据从小到大排列,并且只有1个 99 20 } 21 22 cout << endl; 23 24 return 0; 25 }
打印结果:
======================================================================================================================