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