STL:set详解

来源:互联网 发布:矩阵型组织结构 编辑:程序博客网 时间:2024/06/05 18:45

和vector、list不同,set、map都是关联式容器。set内部是基于红黑树实现的。插入和删除操作效率较高,因为只需要修改相关指针而不用进行数据的移动。

删除set的数据时,实际的操作是删除红黑树中的一个节点,然后相关指针做相关调整。指向其他元素的迭代器还是指向原位置,并没有改变,所以删除一个节点后其他迭代器不会失效。list和map也是同样的道理。
然而删除vector中的某个元素,vector中其他迭代器会失效,因为vector是基于数组的,删除一个元素后,后面的元素会往前移动,所以指向后面元素的迭代器会失效。(插入元素造成内存重新分配的话,所有迭代器都会失效)
再稍微说一下迭代器的实现。迭代器是一个对象,vector的迭代器是封装了数组下标;list、map、set的迭代器是封装了元素节点的指针。
所以set有以下2个特点:
1、search操作效率会很高O(log n)
2、set中元素的值不能直接被改变,但是可以删除某个元素或插入新的元素。
定义:集合(Set)容器是一个按特定顺序存储唯一(Unique)元素的关联容器。
stl中set模板类形式如下:

// <set>template < class T,           class Compare = less<T>,           class Alloc = allocator<T> >> class set;

这里的模板参数:

T元素的类型。在类模板内部,使用其别名为 key_type 及 value_type 的成员类型。Compare一个二元谓词,以两个元素为参数返回一个 bool 值。可以是函数指针(Function pointer)类型或函数对象(Function object)类型。在类模板内部,使用其别名为 key_compare 及 value_compare 的成员类型。Alloc容器内部用来管理内存分配及释放的内存分配器的类型。这个参数是可选的,它的默认值是 std::allocator<T>,这个是一个最简单的非值依赖的(Value-independent)内存分配器。在类模板内部,使用其别名为 allocator_type 的成员类型。

set 容器中的所有元素都是按由类型为 Compare 的比较对象指定的严格弱序规则排序的。并且set支持双向迭代。
另外,从模板来看,set在定义的时候可以把自定义的比较函数当参数传入:

struct myComp  {      bool operator()(const your_type &a,const your_type &b)      [          return a.data-b.data>0;      }  }  set<your_type ,myComp> s; 

或者set元素是自定义的数据结构时,重载自定义数据类型的比较运算符:

struct Info  {      string name;      float score;      //重载“<”操作符,自定义排序规则      bool operator < (const Info &a) const      {          //按score从大到小排列          return a.score<score;      }  }  set<Info> s;

最后整理归纳了stl中set容器支持的操作:

//set支持的操作:set<int> myset,myset1;myset.begin();myset.end();myset.rbegin();myset.rend();myset.size();myset.clear();//清空myset.empty();myset.max_size();myset.count(2);//计算2的个数,set只可能是0或者1myset.insert(2);//插入2/*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.myset.emplace(2);//构造然后插入myset.emplace_hint(2,5);//按提示构造及插入一个元素myset.erase(2);//删除2//erase(iterator)  ,删除定位器iterator指向的值//erase(first,second),删除定位器first和second之间的值//erase(key_value),删除键值key_value的值iterator find (const value_type& val);//在set中查找是使用二分查找,没找到则返回.end()myset.swap(myset1);
1 0
原创粉丝点击