4 关联式容器

    关联式容器是最常见的、也是最有用的容器。关联式容器其实是关联数组概念的扩展。
    关联式容器依据特定的排序准则,自动为其元素排序。关联式容器中的元素都经过排序,是有序的。所有关联式容器都有一个可供选择的template参数。这个参数用以指明排序准则。排序准则是以函数形式体现的,用于比较元素值或键值。默认情况下以"operator<"进行比较排序。程序员也可以提供自定义的比较函数,从而定义出不同的排序准则。

    通常关联式容器由二叉树数据结构实现的。在二叉树中,每个元素都有一个父节点和两个子节点;左子树的所有元素都比该元素的值小,右子树的所有元素都比该元素的值大。关联式容器的差别在于元素的类型以及处理重复元素的方式。关联式容器还能提供对元素的快速访问,但不能实现任意位置的操作。

    主要的关联式容器包括set(集合)、multisets、maps(映射)和multimaps。其中set可视为一种特殊的map,其元素的值即键值。前两种容器是在<set>头文件中声明和定义,后两种容器是在<map>头文件中声明和定义的。

    set是支持随机存取的容器,其键值和实值是同一个值。set型容器中的所有元素必须具有唯一值,即不能包含重复的元素。set型容器中的元素可以实现按照次序来存储一组数值,即在一个集合中元素既作为被存储的数据又作为数据的键值。multiset是另一种类型的容器,其键值和数据元素是同样的值。与set不同的是,它可以包含重复的元素。multiset对象也可以实现按照次序来存储一组数值。

    map是一种包含成对数据的关联数组容器。成对数据中的一个值是实值,另一个值是用来寻找数据的键值。一个特定的关键值只能与一个元素相联系。map是排序结构体,键值是独一无二的。事实上,map的内部结构和set是一样的。set可以看作一种特殊的map,其键值和实值是同一个。multimap是一种允许出现重复键值的关联数组容器。与map对象不同,一个键值可以和多个元素相联系,multimap而且允许键值重复。

set/multiset

    set和multiset会根据特定的排序准则自动将元素排序。该集合更像一个有序链表,其中的元素有顺序存储。

namespace std{
    template<class T,
             class Compare = less<T>,
             class Allocator = allocator<T> >
    class set;
    template<class T,
             class Compare = less<T>,
             class Allocator = allocator<T> >
    class multiset;
}

template参数    

  • T:只要assignable(可赋值)、copyable(可拷贝)、comparable(可比较)的型别T 都可成为set或multiset的元素。
  • Compare: 第二个template参数用来定义排序准则,此参数可有可无,默认采用less(这是一个仿函数,以operator<对元素比较)。
  • Allocator :内存模型。 

排序准则

    可采用两种形式:

  • 在类模板中以参数形式实现
  • 以构造函数参数定义

具体形式如下:

set<int,greater<int>> S1;//第一种形式实现排序规则
set<int> S2(less<int>());//第二种形式实现排序规则

    排序准则需满足:

  1. 反对称;对于operator<而言,若x<y为真,则y<x为假。
  2. 可传递;对于operator<而言,若x<y且y<z为真,则x<z为真。
  3. 非自反;对于operator<而言,x<x恒为假。

    set和multiset通常由平衡二叉树实现。内部结构如下图示:

                                         192333_hDgr_3472252.png

    因为自动排序使set和multiset有一个重要限制:不得随意改变元素的值,否则会打乱原有正确的排序。因此改变元素的值需要先删除旧元素,再插入新元素。

  • set和multiset不提供直接存取元素的任何操作函数
  • 通过迭代器可以进行元素间接存取。有一个限制:从迭代器的角度看元素值是常数。

 set/multiset操作函数

1、构造函数和析构函数

操作效果
set c生成一个空的set/multiset,不含任何元素
set c(op)以op为排序准则,产生一个空的set/multiset
set c1(c2)产生某个set/multiset的副本,所有元素均被复制
set c(beg,end)以区间[beg,end]内的元素产生一个set/multiset
set c(beg,end,op)      以op为排序准则,以区间[beg,end]内的元素产生一个set/multiset
c.~set()销毁所有元素,释放内存

2、非变动性操作

操作效果
c.size()返回容器大小
c.empty()判断容器是否空
c.max_size()返回容器可容纳的最大元素数量
c1==c2判断c1是否等于c2
c1!=c2判断c1是否不等于c2
c1<c2判断c1是否小于c2
c1>c2判断c1是否大于c2
c1<=c2判断c1是否小于等于c2
c1>=c2判断c1是否大于等于c2

*比较操作只能用于型别相同的容器。

3、搜寻操作函数

操作效果
count(elem)返回元素值为elem的元素的个数
find(elem)返回元素值为elem的第一个元素的位置,没有的话返回end()
lower_bound(elem)返回elem的第一个可安插位置,即元素值>=elem的第一个元素位置
upper_bound(elem)返回elem的最后一个可安插位置,即元素值>elem的第一个元素的位置
equal_bound(elem)返回elem可安插的第一个位置和最后一个位置,即元素值==elem的元素区间

 

转载于:https://my.oschina.net/u/3472252/blog/1083550

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值