写在前面:
在写这篇博客之前吐个槽,其实也可不不用这么麻烦这么写博客。讲道理其实在书本上学这些知识应该挺快的。可以书上看一遍记个大概,然后做题的过程中,不断遇见各种小知识,这样分散的积累,然后一定规模后,就可以系统的整理。但是现在先花时间来做这件事,其实也可以,建立主体的框架,后面再慢慢细化丰富。也没必要想那么多,慢慢来。不管方法是什么,重要的是每天要做点事。那么这篇博客学习set容器。目前学习了vector、map容器,都是“浮于表面“地学习容器创建、函数等。没有细究容器实现原理。这里也是提一下这个问题,后面还是有必要仔细学习容器的基本原理。
set类与头文件包含:
STL set容器微软官方译为”集合“。STL 容器类集用于存储和检索集合中的数据,此集合中包含的元素值是唯一的,并且用作数据自动排序所依据的键值。 不能直接更改集中元素的值。 必须先删除旧值,才能插入具有新值的元素。
set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点的左子树的高度与有字数的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意的是,它不会重复插入相同键值的元素,而采取忽略处理。
平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque、和list的容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值从小到大的顺序排列。
构造set集合的主要目的是为了快速检索,使用set前,需要在程序头文件中包含声明“#include”。
#include <set> //注意,STL头文件没有扩展名.h
set语法表达如下:
template <
class Key,
class Traits=less<Key>,
class Allocator=allocator<Key> >
class set
- Key::要存储在集中的元素数据类型。
- Traits:一种提供函数对象的类型,该函数对象将两个元素值作为排序键进行比较,以确定其在集中的相对顺序。 此参数是可选的为二元谓词较少 * <> > *是默认值。
- Allocator:一种表示存储的分配器对象的类型,该分配器对象封装有关集的内存分配和解除分配的详细信息。 此参数是可选的而默认值是分配器<> >。
set::set
这次就不想之前那样分开写了。直接在程序中添加必要注释。
using namespace std;
// 创建一个空set。元素类型为int
set <int> s0;
// 创建一个set,并指定元素比较方式,less<int> ,然后插入4个元素
set <int, less<int> > s1;
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(40);
// 创建一个set,并指定元素比较方式,less<int> ,然后插入2个元素
set <int, less<int> > s2;
s2.insert(10);
s2.insert(20);
// 创建一个set,使用s1的分配器。
set <int>::allocator_type s1_Alloc; //创建一个分配器
s1_Alloc = s1.get_allocator(); //获取s1的分配器
set <int> s3(less<int>(), s1_Alloc);
s3.insert(30);
// 通过拷贝一个set的方法创建一个set
set <int> s4(s1);
// 通过拷贝[first,last]的部分创建一个set
set <int>::const_iterator s1_bcIter, s1_ecIter;
s1_bcIter = s1.begin();
s1_ecIter = s1.begin();
s1_ecIter++;
s1_ecIter++;
set <int> s5(s1_bcIter, s1_ecIter);
// 结合部分拷贝与分配器的方式创建一个set
set <int>::allocator_type s2_Alloc;
s2_Alloc = s2.get_allocator();
set <int> s6(s4.begin(), ++s4.begin(), less<int>(), s2_Alloc);
// 通过移动s5创建s7.s5为空。s7为新的s5
set<int> s7(move(s5));
cout << "s7 =";
for (auto i : s7)
cout << " " << i;
cout << endl;
// 通过一个初始列表创建set
cout <<