set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的数据结构,在插入元素时,
它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于
左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点左子树的高度
与右子树的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意的是,
它不会重复插入相同键值的元素,而采取忽略处理。
set采用*.insert(*)方法把元素(int)插入集合中去,是按序插入的,默认升序,也可以自定义比较函数:
set<int,myComp> s;
例1:插入的元素不是结构体
#include <iostream>
#include <set>
using namespace std;
//自定义的比较函数为结构体才行
//重载了()运算符,是双目运算符,可以带2个参数
struct Comp
{
bool operator () (const int &a, const int &b)
{
return a>b;
}
};
int main(int argc, char* argv[])
{
// set<int> s;
set<int, Comp> s;
s.insert(3);
s.insert(9);
s.insert(8);
s.insert(12);
for (auto i = s.begin(); i != s.end();i++)
{
cout << *i << endl;
}
system("pause");
return 0;
}
例2:如果插入的元素是结构体,可以直接把比较函数写在结构体内:
<pre name="code" class="cpp">#include <set>
#include <string>
#include <iostream>
using namespace std;
struct Info //也可以定义为class
{
string name;
float score;
//重载“<”操作符,自定义排序规则
bool operator < (const Info &a) const
{
//按score由大到小排列。如果要由小到大排列,使用“>”号即可。
return a.score<score; } //最好写成:return this.score>a.score,第一个参数设置为this指针所指
};
int main(int argc, char* argv[])
{
//定义元素类型为Info结构体的集合对象s,当前没有任何元素
set<Info> s;
//定义Info类型的元素
Info info;
//插入3个元素
info.name="Jack";
info.score=80.5;
s.insert(info);
info.name="Tomi"; //此处info.name=Jack,也可以成功插入,因为score不同
info.score=20.5;
s.insert(info);
info.name="Nacy";
info.score=60.5;
s.insert(info);
set<Info>::iterator it;//定义前向迭代器
for(it=s.begin();it!=s.end();it++)
{
cout<<(*it).name<<" : "<<(*it).score<<endl;
}
return 0;
}
反转:
vector:reverse(ivec.begin(), ivec.end());
set反转:没有反转算法,但有反转迭代器:set<int>::reverse_iteratorrit;//定义反向迭代器
for(rit=s.rbegin();rit!=s.rend();rit++) ……
注:
为何每次insert之后,以前保存的iterator不会失效?
iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。
.end()返回的是最后一个元素的下一个位置。
insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void.