set集合容器是使用红黑树[一种二叉检索树的数据结构]来组织泛化的元素数据。元素数据的检索使用的是二叉检索树的中序遍历算法,检索的效率高于vector、deque、和list等容器,由于采用中序遍历算法可以将二叉检索树中的键值由小到大遍历出来,所以set集合容器蕴含了元素间的有序性。红黑树的每个节点包含一个取值为红色或者黑色的颜色域,节点键值的插入必须确保树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值,不会将重复的键值插入容器,也不会指定具体的插入位置,所以set集合容器所包含的元素必须是唯一的,不能插入重复的元素。元素检索的时间复杂度为O(logn),对2^100个元素进行检索只需要100次比较,set集合容器具有高效的元素插入、检索和删除。
主要有以下几种方式。
(1) set()
set<int> s;//创建了空的set对象s
(2) set(const key_compare& cmp)
用一个比较函数的对象cmp来创建一个set对象。
//定义字符串比较函数对象strLess
struct strLess
{
bool operator()(const char*s1,const char*s2)const
{
return strcmp(s1,s2)<0;
}
};
//创建set容器对象s
set<const char*,strLess> s(strLess());
(3) set(const set&)
拷贝构造。
//set<int> s1;
set<int> s2(s1);
(4) set(InputIterator first,InputIterator last)
int array[]={1,2,3};
set<int> s(array,array+3);
(5) set(InputIterator first,InputIterator last, const key_compare& cmp)
用迭代区间[first,last)所指的元素和cmp函数对象,创建一个set对象。
const char* array[]={“hello”,”world”};
set<const char*,strLess> s(array,array+2,strLess());
set元素的插入一般使用insert进行动态检索插入,三个insert函数可以将一个元素或者一个迭代区间插入set容器。
(1) pair<iterator,bool>insert(const value_type& v)
(2) iterator insert(iterator pos, const value_type& v)
(3) void insert(InputIterator first,InputIterator last)
对于迭代区间的重复元素,只会插入一个。
如果希望提供一个是否插入成功的信息,可以使用pair对象的insert函数进行插入。
set<int> s;
s.insert(10);
pair<set<int>::iterator,bool> p=s.insert(19);
if(p.second)
cout<<"插入新元素"<<*(p.first)<<endl;
else
cout<<"该元素以及存在,插入失败"<<endl;
set容器具有高效的红黑树元素的删除处理,并自动重新调整内部的红黑树平衡,下面的删除函数可以删除某个迭代器位置上的元素、等于某个键值的元素,一个区间上的元素,容器内的所有元素。
(1) void erase(iterator pos)
(2) size_type erase(const key_type& k)
(3) void erase(iterator first,iterator last)
(4) void clear()
利用迭代器访问红黑树内部的元素。
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
//无序插入
s.insert(1);
s.insert(5);
s.insert(4);
s.insert(3);
s.insert(2);
set<int>::iterator begin,end;
end=s.end();
for(begin=s.begin();begin!=end;begin++)
{
cout<<*begin<<" ";//有序输出
}
cout<<endl;
return 0;
}
可以看出,由于红黑树中序遍历的机制,使得set集合容器虽然无序插入,但是有序输出。
利用反向迭代器reverse_iterator和const_reverse_iterator,可以实现红黑树的逆中序遍历,将元素从大到小遍历出来。
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
//无序插入
s.insert(11);
s.insert(50);
s.insert(14);
s.insert(30);
s.insert(27);
s.insert(27);//不会重复插入
set<int>::reverse_iterator rbegin,rend;
rend=s.rend();
for(rbegin=s.rbegin();rbegin!=rend;rbegin++)
{
cout<<*rbegin<<" ";
}
return 0;
}
利用set容器提供的find函数可以对红黑树进行搜索,返回的迭代器值为搜索到的元素的位置,其原型为:
iterator find(const key_type&k) const
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(1);
s.insert(3);
s.insert(15);
s.insert(10);
s.insert(11);
s.insert(21);
int v=15;
set<int>::iterator i=s.find(v);
cout<<*i<<endl;
v=20;
i=s.find(v);
if(i!=s.end())
cout<<*i<<endl;
return 0;
}
集合容器set还提供其他函数,如empty、size、swap、lower_bound、upper_bound和equal_range等。