STL之容器set、multiset、unordered_set、unordered_multiset

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

set和multiset

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

# include<set>

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

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

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

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

1. 定义和初始化

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

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

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

set<T> serven;            // set的默认构造函数
multiset<T> serven;       // multiset的默认构造函数
set(const set& serven);   // 拷贝构造函数

​
set<int> serven_1;
set<int> serven_2(serven_1);
multiset<int> 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<int>::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<int>::iterator find_it = serven_2.find(3);
cout<<"serven_2中key为3的元素:"<<*find_it<<endl;
//set<int>::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>

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

2. set和unordered_set的区别

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

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

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 32
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三贝勒文子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值