关联容器

Posted on 2019-01-05 14:45  Summer_8918  阅读(149)  评论(0)    收藏  举报

《C++ Primer》第五版 读书笔记

关联容器和顺序容器的不同:关联容器中的元素是按关键字来保存和访问的。顺序容器是按它们在容器中的位置来保存和访问的。

关联容器支持高效的关键字查找和访问。两个主要的关联容器:类型是map和set.

map中的元素是一些关键字-值(kay-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。

set中每个元素值包含一个关键字;set支持高效的关键字查询操作——检查一个给定关键字是否在set中。

标准库提供8个关联容器

按关键字有序保存数据

map

关联数组;保存关键字-值对

Set

关键字即值,只保存关键字的容器

Multimap

关键字可重复出现的map

Multiset

关键字可重复出现的set

无序集合

Unordered_map

用哈希函数组织的map

Unordered_set

用哈希函数组织的set

Unoedered_multimap

哈希组织的map;关键字可重复出现

Unordered_multiset

哈希组织的set;关键字可重复出现

 

1 关联容器支持普通容器操作

(1)类型别名

iterator

const_iterator

size_type

difference­_type

value_type

reference

const_reference

 

 

(2)构造函数

C c

C c1(c2)

C c(b,e)

C c{a,b,c,…}

(3)赋值与swap

c1=c2

c1={a,b,c,…}

a.swap(b)

swap(a,b)

(4)大小

c.size()

c.max_size()

c.empty()

(5)添加删除元素

c.insert(args)

c.emplace(inits)

c.erase(args)

c.clear()

(6)关系运算符

==,!=  所有容器都支持

<,<=,>,>=  无序关联容器不支持

(7)获取迭代器

c.begin()

c.end()

c.cbegin()

c.cend()

(8)反向容器的额外成员

reverse_iterator

const_reverse_iterator

c.rbegin()

c.rend()

c.crbegin()

c.crend()

 

关联容器中的元素是根据关键字存储的,不支持顺序容器的位置相关操作,也不支持构造函数或插入操作。关联容器的迭代器都是双向的。

map的元素是pair,pair类型的标准库,定义在头文件utility中。

pair的数据成员是public的,两个成员分别命名为first和second。

 

2 关联容器操作

关联容器额外的类型别名

key_type

关键字类型

mapped_type

关键字关联的类型,仅适用于map

value_type

对于set,与key_type相同

对于map,为pair<const key_type,mapped_type>

 

不能改变一个元素的关键字,因为pair的关键字部分是const的。因此通常不对关联容器使用泛型算法,关键字是const意味着不能讲关联容器传递给修改或重排容器的算法。关联容器可用于只读取元素的算法。使用关联容器定义的专用的find成员会比调用泛型find快得多。

泛型copy算法可以将元素从一个关联容器拷贝到另一个序列。

调用inserter将一个插入器绑定到一个关联容器。

关联容器insert操作

c.insert(v)

c.emplace(args)

c.insert(b,e)

c.insert(i1)

c.insert(p,v)

c.emplace(p,args)

 

insert或emplace返回的值类型依赖于容器类型和参数。

从关联容器删除元素,使用erase

map的下标操作

map和unordered_map容器提供了下标运算符和一个对应的at函数.set不支持下标操作。

c[k]

返回关键字k的元素;若k不在c中,添加一个关键字为k的元素,对其值进行初始化

c.at(k)

访问关键字为k的元素,带参数检查;若k不在c中,抛出out_of_range异常

 

map与vector和string不同,map的下标运算返回的类型与解引用map迭代器得到的类型不同。

在一个关联容器中查找元素的操作

lower_bound和upper_bound不适用于无序容器

c.find(k)

返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器

c.count(k)

返回关键字等于k的元素的数量。对于不允许重复关键字的容器,返回值永远是0或1

c.lower_bound(k)

返回迭代器,指向第一个关键字不小于k的元素

c.upper_bound(k)

返回迭代器,指向第一个关键字大于k的元素

c.equal_range(k)

返回一个迭代器pair,表示关键字等于k的元素的范围。若k不存在,pair的两个成员均等于c.end()

 

3 无序容器

新标准定义了4个无序关联容器。无序容器不是使用比较运算符来组织元素,而是使用哈希函数和关键字类型的==运算符。

如果关键字类型固有就是无序的,或者性能测试发现问题可以用哈希技术解决,就可以使用无序容器。

无序容器在存储上组织为一组桶,每个桶保存零个或多个元素。无序容器使用一个哈希函数将元素映射到桶。

无序容器的性能依赖于哈希函数的质量和桶的数量和大小。