STL--set介绍及set的使用
1.set介绍(1)set是STL中一个很有用的容器,用来存储同一种数据类型的数据结构(可以称之为K的模型),基本功能与数组相似。(2)set与数组不同的是,在set中每个元素的值都是唯一的。(3)而且set插入数据时,能够根据元素的值自动进行排序。(4)set中数元素的值并不能直接被改变。2.set的底层(1)set的底层是红黑树,是红黑树里面K的模型;K模型:...
1 set介绍
(1)set是STL中一个很有用的容器,用来存储同一种数据类型的数据结构(可以称之为K的模型),基本功能与数组相似。
(2)set与数组不同的是,在set中每个元素的值都是唯一的。
(3)而且set插入数据时,能够根据元素的值自动进行排序。
(4)set中数元素的值并不能直接被改变。
2 set的底层
(1)set的底层是红黑树,是红黑树里面K的模型;
K模型:表示只能存放同一种数据类型
KV模型:表示能存放两种数据类型
(2)map的底层也是红黑树,而它是KV模型。
(3)set不允许插入重复数据,而multiset允许插入相同的数据。
补充:multiset:multiset功能与set类似,接口也基本一样,最主要的区别是:set不允许数据冗余,而multiset允许数据冗余
3 set里面的一些变量定义
(1)set的模板参数介绍
template < class T, // 表示set里面存放的数据类型
class Compare = less<T>, // 仿函数,可以指定让set按照什么方式进行比较数据
class Alloc = allocator<T> // 空间配置器,默认是系统提供的
>
(2)第二个模板参数Compare为仿函数,表示按照何种方式进行数据的比较,因为set进行遍历是有序的,当前仿函数的比较方式让set遍历的序列是递增的序列;如果想要让set遍历的序列为递减序列,就可以将第二个模板参数改为greater;另一方面如果set里面存放的是自定义类型,则必须自己实现一个仿函数用于支持两个自定义类型大小的比较。
(3)第三个模板参数Alloc为空间配置器。
4 set相关接口介绍
4.1 插入数据(接口为insert)
set的进行数据的插入有三种方式
pair<iterator,bool> insert (const value_type& val);
iterator insert (iterator position, const value_type& val);
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
4.1.1 pair介绍:
(1)pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
(2)pair的实现:
template<class T1,class T2>
struct pair
{
pair(T1 _first, T2 _second)
:first(_first)
, second(_second)
{}
T1 first;
T2 second;
};
(3)将两个数据合成一个数据不仅可以使用pair创建对象的方式,还可以用make_pair,make_pair是一个模板函数。
make_pair的实现:
template<class T1,class T2>
pair<T1, T2> make_pair(T1 first, T2 second)
{
return pair<T1, T2>(first, second);
}
4.1.2 插入方式介绍
1.方式1:pair<iterator,bool> insert (const value_type& val);
(1)返回一个pair,pair里面包含两种数据类型,一个是迭代器,一个是bool类型;
(2)pair的第一个参数为该set的迭代器,表示如果插入一个set里面不存在的数据,则迭代器指向这个新增结点,如果插入一个set里面已经存在的数据,则迭代器指向已经存在的数据;
(3)pair的第二个参数为bool类型,表示如果是true,则数据成功插入,如果为false则表示插入的数据已经存在。
2.方式2:在某个位置上插入一个数据,iterator insert (iterator position, const value_type& val);
3.方式3:将一个区间的数据插入
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
InputIterator为迭代器的类型
注意:multiset返回的都是新的数据(因为不论数据是否存在,都会成功插入除非内存已满,内存满也会抛异常)。
4.2 set的遍历
4.2.1 遍历方式介绍
(1)用迭代器(默认是采用升序方式,如果采用反向迭代器或者将仿函数由默认less改成greater则可以输出降序的数据);
①正向迭代器
set<int>::iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1 << " ";
++it1;
}
②反向迭代器
set<int>::reverse_iterator it1 = s.rbegin();
while (it1 != s.rend())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
③const迭代器(C++11里面);
4.2.2 set进行遍历注意点
(1)红黑树的遍历是走的中序,则s.begin()是红黑树的最左结点;
(2)s.end()是最后一个数据的下一个位置;
(3)++it1仍然是按照中序的方式(左根右);
4.2.3 set删除数据(接口为erase)
(1)删除某个位置:
void erase (iterator position);
s.erase(s.find(5));
注意:如果利用该方式删除一个不存在的数据,应该要加判断,如:
set<int>::iterator pos = s.find(10);
if (pos != s.end()) //!=s.end()说明数据存在
{
s.erase(pos);
}
(2)删除某个值(相当于Remove)
size_type erase (const value_type& val);
set<int> s;
s.insert(6);
s.insert(5);
s.insert(3);
s.insert(7);
s.insert(2);
s.insert(1);
set<int>::iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
s.erase(3);
it1 = s.begin();
while (it1 != s.end())
{
cout << *it1 << " ";
++it1;
}
}
注意:multiset删除某个值时,将里面与该值相等的所有数据全部删除。
(3)删除某个区间:void erase (iterator first, iterator last);
利用该方式删除的是一个左闭右开的区间;(即last表示最后一个删除数据的下一个位置);
4.2.3 set查找数据(接口为find)
iterator find (const value_type& val) const;
4.2.4 count(统计数据是否存在于set里面)
size_type count (const value_type& val) const;
(1)返回值只有0或1;
(2)如果返回1说明查找的数据存在,如果查找的数据不存在则返回零。
注意:multiset的count返回该值出现的次数;
4.2.5 swap
(1)交换两个set,接口及参数如下:void swap (set& x);
(2)底层是将两个set的根进行交换
更多推荐
所有评论(0)