首页 > 学院 > 开发设计 > 正文

STL之set

2019-11-08 19:26:08
字体:
来源:转载
供稿:网友

首先要知道set是STL中的一种标准关联容器(例如set,map,multiset,multimap都是标准关联容器,而像vector,list,string,deque这些都是序列容器),那什么是关联式容器,什么又是序列容器呢? 关联容器与序列容器的区别在于:关联容器是通过键存储和读取元素的,而序列容器则是通过元素在容器中的位置顺序存储和访问元素的。 set特性: set的底层其实就是使用平衡搜索树——红黑树(RB-tree)实现的,所以他的插入和删除操作只需要用迭代器操作节点即可完成(但不能通过迭代器改变它的元素值,因为它的键值就是元素值,改变会影响它的排列规则,当然STL也不会给你改变键值的接口),不需要内存移动和拷贝,所以效率函数比较高的。另外set里所有元素都会根据键值自动被排列(并且默认进行升序排列),跟map不同的是,map同时拥有实值和键值,而set只有键值,或者说它的实值就是键值,键值就是实值,同时set不允许两个元素有相同的键值。 set的标准形式是

template < class T, // set::key_type/value_type class Compare = less<T>, // set::key_compare/value_compare class Alloc = allocator<T> // set::allocator_type > class set;

这里写图片描述

我们来看看set的接口: 由于set底层是由RB-tree实现的,所以set的大部分接口红黑树都提供了,几乎都在转调用RB-tree的操作。

insert接口中原型是这样的:

这里写图片描述

pair类型: pair模板类用来绑定两个对象为一个新的对象,该类型在头文件中定义。pair类型提供的操作如下表: pair

template<typename K, typename V>struct pair{ K first; V value;}

现在因为它的value是不存在的,前面说过它只有键值,value存的是bool类型,如果插入成功返回true,失败返回false。 这里insert有两种情况,一种是已存在的,一种不存在的,不存在的返回的pair是返回插入的迭代器,bool返回的是ture,对于已经存在的,返回的是已经存在的迭代器,第二个参数bool返回false。下面可以验证一下。

std::set<int> s; s.insert(3); pair<set<int>::iterator, int > ret1 = s.insert(4); s.insert(ret1.first, 12); cout << ret1.second << endl; pair<set<int>::iterator, int >ret = s.insert(3); cout<<ret.second<<endl; system("pause"); return 0;

输出的是1 0也就是对应的true false。 最后验证一下它不允许两个相同键值存储:

int main(){ set<int> s; s.insert(5); s.insert(2); s.insert(3); s.insert(1); s.insert(3); set<int>::iterator it = s.begin(); while (it != s.end()) { cout << *it << " "; it++; } cout << endl; system("pause"); return 0;}

这里写图片描述 发现set已经按照默认升序排列完成,并且没有将重复出现的3插入。

最后需要注意的是set::find()这个函数,它在找到这个元素时会返回所在位置迭代器,如果没有找到会返回set::end();不能对其进行访问,因为这不是你的有效空间,访问是不安全的。 例如下面这种操作:

set<int> s; s.insert(5); s.insert(2); s.insert(3); s.insert(1); s.insert(3); set<int>::iterator it = s.find(7); cout << *it << endl;
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表