> 文档中心 > STL之容器set、multiset、unordered_set、unordered_multiset

STL之容器set、multiset、unordered_set、unordered_multiset

    set和map都是属于关联性容器,它们的底层实现原理都是红黑树

set和multiset

    使用set和multiset需要添加的头文件:

# include

    容器set和multiset的操作都一样,唯一的区别就是multiset中的数据是可以重复的。

    Set的特性是。所有元素都会根据元素的键值自动被排序。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值。

    我们可以通过set的迭代器改变set元素的值吗?不行,因为set元素值就是其键值,关系到set元素的排序规则。如果任意改变set元素值,会严重破坏set组织。换句话说,set的iterator是一种const_iterator.

    set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,只有被删除的那个元素的迭代器才无效。

1. 定义和初始化

  • set serven:调用set的默认构造函数

  • multiset serven:调用multiset的默认构造函数

  • set(const set& serven):调用set的拷贝构造函数

set serven;     // set的默认构造函数multiset serven;       // multiset的默认构造函数set(const set& serven);   // 拷贝构造函数​set serven_1;set serven_2(serven_1);multiset serven_3;

2. set的赋值操作

  • set& operator=(const set& serven):重载等号操作符

  • swap(serven):交换两个集合容器

// set& operator=(const set& serven);        重载等号操作符// swap(serven);                             交换两个集合容器​/* set的赋值操作 */serven_2 = serven_1;//serven_3.swap(serven_1);    // set和multiset不能相互转换,因为数据结构不一样

3. set的插入和删除操作

  • insert(val):插入元素val;

  • clear():清空整个set容器;

  • erase(pos):擦除pos位置的元素;

  • erase(begin,end):擦除区间[begin,end)中的数据;

  • erase(val):擦除容器中值为val的元素。

/* set的插入操作 */// insert插入元素serven_1.insert(1);serven_1.insert(2);serven_1.insert(1);serven_1.insert(4);serven_1.insert(3);serven_1.insert(8);serven_1.insert(5);serven_1.insert(6);serven_1.insert(9);serven_1.insert(7);serven_1.insert(10);​​set::iterator set_it1;cout<<"serven_1的元素为:"<<endl;set_it1 = serven_1.begin();while(set_it1 != serven_1.end()){  cout<<*set_it1<<" ";  set_it1++;}cout<<endl<<endl;​​// 删除元素serven_1.erase(2);cout<<"删除serven_1元素为2后:"<<endl;set_it1 = serven_1.begin();while(set_it1 != serven_1.end()){  cout<<*set_it1<<" ";  set_it1++;}cout<<endl<<endl;​​serven_1.erase(++serven_1.begin());cout<<"删除serven_1第二个元素后:"<<endl;set_it1 = serven_1.begin();while(set_it1 != serven_1.end()){  cout<<*set_it1<<" ";  set_it1++;}cout<<endl<<endl;​​​serven_1.erase(++++serven_1.begin(),--serven_1.end());cout<<"删除serven_1第三个到倒数第二个元素后:"<<endl;set_it1 = serven_1.begin();while(set_it1 != serven_1.end()){  cout<<*set_it1<<" ";  set_it1++;}cout<<endl<<endl;​​// 清除所有元素serven_1.clear();cout<<"清除serven_1所有元素后:"<<endl;set_it1 = serven_1.begin();while(set_it1 != serven_1.end()){  cout<<*set_it1<<" ";  set_it1++;}cout<<endl<<endl;

运行结果:

4. set的大小操作

  • size():返回容器的大小;

  • empty():返回容器是否为空。

/* set的大小操作 */  serven_1.insert(1);  serven_1.insert(2);  serven_1.insert(1);  serven_1.insert(4);  serven_1.insert(3);  serven_1.insert(8);  serven_1.insert(5);  serven_1.insert(11);  serven_1.insert(9);  serven_1.insert(7);  serven_1.insert(10);​  /* set的赋值操作 */  serven_2 = serven_1;  //serven_3.swap(serven_1);    // set和multiset不能相互转换,因为数据结构不一样​​  cout<<"清除serven_1所有元素后:"<<endl;  set_it1 = serven_2.begin();  while(set_it1 != serven_2.end()){    cout<<*set_it1<<" ";    set_it1++;  }  cout<<endl<<endl;​  cout<<"serven_2的大小为:"<<serven_2.size()<<endl;  cout<<"serven_2是否为空:"<<serven_2.empty()<<endl<<endl;

运行结果:

5. set的查找操作

  • find(key):查找key,返回迭代器,找不到则返回set.end();

  • count(key):查找键key的元素个数;

  • lower_bound(keyval):返回第一个key>=keyval元素的迭代器;

  • upper_bound(keyval):返回第一个key>keyval元素的迭代器;

  • equal_range(keyval):返回容器中key与keyval相等的上下限的两个迭代器。

/* set的查找操作 */set::iterator find_it = serven_2.find(3);cout<<"serven_2中key为3的元素:"<<*find_it<<endl;//set::iterator find_it = serven_2.find(6);      // 没有6元素,所以找不到会返回迭代器的end​​  /* set的计数问题 */cout<<"serven_2中key为2的元素个数:"<<serven_2.count(2)<<endl<<endl;

运行结果:

unorder_set 和 unorder_multiset

1. unordered_set的头文件

# include

unordered_set的操作都跟set相似,没啥区别。

2. set和unordered_set的区别

set unordered_set
有无序 有序 无序
底层数据结构 红黑树 哈希表
空间内存占用率 空间占用率高 占用内存高
执行效率 执行效率低 执行效率高
适用性 有顺序要求 查找频繁要求

欢迎关注微信公众号 “三贝勒文子” ,每天学习C++