Set和Multiset会根据特定的排序规则,自动将元素排序.
两者不同的地方:
Multiset允许元素重复,Set不允许
头文件<Set>
所谓的less,就是一个结构:
可以看到以operator<对元素进行比较,如果没有传入某个排序准则,就采用默认的准则less,此外还有以下的比较结构:
所谓的排序准则,其意义如下:
1.非对称的:对operator<而言,如果x<y为true, 则y < x为false,如果op(x,y)为true,则op(y,x)为false
2.可传递的:对operator<而言,如果x<y为true且y<z为true,则x < z为true,如果op(x,y)为true且op(y,z)为true,则op(x,z)为false
3.非自反的:对operator<而言, x < x永远为false.对op()而言,op(x,x)永远为false
4.等效传递性:如果a等于b且b等于c,那么a等于c
根据这些性质,排序准则也被用来检查等效性,两个元素如果没有任何一个小于另一个,则它们被视为重复
Set和Multiset的能力
可以看到 Set和Multiset都是继承了二叉树,通常就是以红黑树完成.
自动排序的主要优点让二叉树查找元素时拥有比较好的性能,具有对数复杂度.
但是自动排序也有一个重要的限制:你不能直接改变元素值,因为这样会打乱原来正确的顺序.
因此要改变元素值,必须先删除旧元素,在插入新元素
Set和Multiset的操作函数
构造函数和析构函数
有两种方式可以定义排序准则:
1.以模板参数定义,例如:
std::set<int, std::greater<int>>coll;
2.以构造函数参数定义:
template<typename T>
inline void PRINT_ELEMENTS(const T & coll, const std::string & optstr = "")
{
std::cout << optstr;
for (const auto & elem : coll)
{
std::cout << elem << ' ';
}
std::cout << std::endl;
}
class RuntimeCmp
{
public:
enum cmp_mode {
normal, reverse };
private:
cmp_mode mode;
public:
RuntimeCmp(cmp_mode m = normal) :mode(m) {
}
template<typename T> bool operator()(const T& t1, const T& t2)const
{
return mode == normal ? t1 < t2 :