例说数据结构&STL(八)——set

1 白话集合(set)
  set容器属于关联式容器,与STL另一个容器map一样容器中包含键值对,值不高它的键与值都是同一个数。set实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值;另外,还得保证根节点左子树的高度与右子树高度相等。
  平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器,另外使用中序遍历可将键值按照从小到大遍历出来。构造set集合主要目的是为了快速检索,不可直接去修改键值。
  此外set和我们数学上学习的集合一样,容器中不包含重复数据,并且加载的数据会自动进行从小到大排序入集合。
2 STL中set实战
 2.1 包含set的头文件

#include<set>

using namespace std; // std命名空间,或者std::set< >

 2.2 声明set对象

set<int> set_fir;

 2.3 插入元素

set<int> set_fir;

set_fir.insert(1); //插入自动排序

set_fir.insert(set_fir.begin(),10); //插在哪都一样,都是自动排序

  其实我们只要第一种默认插入方式即可,因为新添加的数据无论在哪容器会自动调整set结构来排序。
 2.4 边界元素

set<int>::iterator iter1 = set_fir.lower_bound(2); //返回set中>=2的索引(迭代器),切记不是小于2的有意思

set<int>::iterator iter2 = set_fir.upper_bound(2); //返回set中>2的索引

  由于set中键和值是同一个值,并且set是自增排序的,所以间接访问*iter1中的数据就是set中第一个大于或者等于2的值。
 2.5 删除元素

set<int> set_fir;

set_fir.erase(2); //删除set中元素2

set_fir.erase(set_fir.begin(), set_fir.end()); //清空整个set

 2.6 查找元素

set<int>::iterator iter;
iter=set_fir.find(5);    // 查找键值为5的元素

if(iter!=set_fir.end())    
    cout<<*iter<<endl;     // 找到就打印出元素

 2.7 迭代器
  关联式容器也可以通过迭代器间接访问每个元素,迭代器可以象征性的看成是指针。set和其他能够使用迭代器的容器一样,它的迭代器是双向的,我们可以从头到尾,也可以从尾到头访问每个数据。

#include<iterator> 

set<int>::iterator iter; //对应迭代器对象

//从头到尾间接访问
for(iter=set_fir.begin();iter!=set_fir.end();iter++)
    cout<<*iter<<endl;  

  从尾到头有对应的索引:

set<int>::reverse_iterator iter; //对应反向迭代器对象
//从尾到头间接访问
for(iter=set_fir.rbegin();iter!=set_fir.rend();iter++)
    cout<<*iter<<endl;  

  上面begin()指向的是set集合中首元素地址,而end()指的是集合中尾部数据的下一位地址。在反向迭代器操作中,rbegin()指向的是set尾部数据,而rend()指向第一个元素前面一个位置的元素(这个元素被认为是反转后的尾部)。此外,切记上面反转迭代也是iter++,而不是我们想的iter–,这个过程set内部已经帮忙转换。
 2.8 其他常用操作

set<int> set_fir;

set_fir.count(12);     // 返回set中元素的个数,由于set的特殊性,所以结果只有0或者1

set_fir.swap(set_sed); // 交换所有数据,需要确保set中元素类型相同

set_fir.clear();       // 清空集合set_fir

set_fir.size();        // 统计set_fir中元素个数

set_fir.empty();       // 判断set中是否为空,空则返回1

3 小结
  上面介绍了集合数据结构特点以及STL中包含的接口。由于集合是基于红黑树构建的数据结构,所以其存取,访问等时间复杂度都为O(logn),n为集合中元素的个数。
  以上是个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢!
  转载请注明出处:http://blog.csdn.net/fx677588/article/details/76365495

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值