STL容器之set、map、unordered_set、unordered_map

上一篇:STL容器之vector、list

1、有序集合set

2、有序字典map

3、无序集合unordered_set和无序字典unordered_map 

下一篇:STL容器之string、stack、queue、bitset


1、有序集合set

    set通常是由平衡二叉树实现出来(通常用红黑树实现),在二叉树中,每个节点都有一个父节点和两个子节点,左子树的所有元素都比自己小,右子树的所有元素都比自己大。set的主要优点是,它能很快找出一个具有某特定value的元素,因为它具备对数的复杂度,而对于循序式容器的复杂度是线性的。然而它的一个缺点是,你不能直接改变元素的value,因为那会破坏元素的自动排序。

set<int> s1

set<int> s1(op)

set<int> s2 = s1

set<int> s2(s1)

set<int> s2(beg, end)

set<int> s2(beg, end, op)

set<int> s2(initlist)

set<int> s2 = initlist

s2.~set()

set<int>

set<int, op> 

默认构造函数,建立一个空的set

建立一个空的set,以op作为排序规则

Copy构造函数,为相同类型的另一个set建立一份拷贝,所有元素均被复制

Copy构造函数,为相同类型的另一个set建立一份拷贝,所有元素均被复制

以区间内的元素作为初值,建立一个set

以区间内的元素为初值,以op为排序准则,建立一个set

以初值initlist的元素为初值建立一个set

以初值initlist的元素为初值建立一个set 

销毁所有的元素,释放内存

一个set,以less<>(operator <)为排序准则

一个set,以op为排序准则

s.key_comp()返回“比较准则”
s.value_comp()返回针对value的“比较准则”,和key_comp()相同
s.count(val)返回元素值为val 的元素个数
s.find(val)返回元素值为val 的第一个元素,如果找不到就返回end()
s.lower_bound(val)返回val的第一个可安插位置,就是元素值>=val的第一个元素位置
s.upper_bound(val)返回val的最后一个可安插位置,就是元素值>val的第一个元素位置
s.equal_range(val)返回val可被安插的第一个位置和最后一个位置,就是元素值==val的元素区间
s1.swap(s2)交换s1和s2的数据
swap(s1, s2)交换s1和s2的数据
s.rbegin()返回反向iterator指向的反向迭代的第一个元素
s.rend()返回反向iterator指向的反向迭代最后一个元素的下一个位置
s.crbegin()返回const iterator反向迭代的第一个元素
s.crend()返回const iterator反向迭代的最后一个元素的下一个位置
s.insert(val)安插一个val拷贝,并返回新元素位置
s.insert(pos, val)安插val的拷贝,返回新元素位置,pos是个提示,指出安插动作的查找起点
s.insert(beg, end)将区间内所有元素拷贝到s,无返回值
s.insert(initlist)插入initlist所有元素,无返回值
s.emplace(args...)插入一个以args为初值的元素,并返回新元素位置
s.emplace_hind(pos, args...)插入一个以args为初值的元素,并返回新元素位置,pos是个提示,指出安插动作的查找起点
s.erase(val)移除与val相等的所有元素,返回被移除的元素个数
s.erase(pos)移除iterator位置pos上的元素,无返回值
s.erase(beg, end)移除区间内的所有元素,无返回值

2、有序字典map

    map和set类似,通常由平衡二叉树完成,可以把set看作特殊的map,只不过set的key和value是同一对象。因此,map拥有set的所有能力和所有操作。唯一的区别是map的元素key/value的键值对,此外map可以作为关联式数组来运用。map会根据key自动对元素排序,这一性质使得map身上有一条重要限制:你不可以直接改变元素key,因为这会破坏正确次序,要修改元素的key,必须先移除拥有该key的元素,然后插入拥有新key/value的元素。

map<int> m1

map<int> m1(op)

map<int> m2 = m1

map<int> m2(m1)

map<int> m2(beg, end)

map<int> m2(beg, end, op)

map<int> m2(initlist)

map<int> m2 = initlist

m2.~map()

map<key, val>

map<key, val, op> 

默认构造函数,建立一个空的map

建立一个空的map,以op作为排序规则

Copy构造函数,为相同类型的另一个map建立一份拷贝,所有元素均被复制

Copy构造函数,为相同类型的另一个map建立一份拷贝,所有元素均被复制

以区间内的元素作为初值,建立一个map

以区间内的元素为初值,以op为排序准则,建立一个map

以初值initlist的元素为初值建立一个map

以初值initlist的元素为初值建立一个map

销毁所有的元素,释放内存

一个map,以less<>(operator <)为排序准则

一个map,以op为排序准则

m[key]如果关键字为key的元素不存在,则安插关键字为key的元素,如果不设置value,value默认初始化为0。如果存在则返回value值。
m.at(key)返回key对应的value,如果该元素不存在则抛出异常

for(auto iter = m.begin();iter!=m.end();iter++){

    cout<<iter->first<<endl;

    cout<<iter->second<<endl;

}

遍历map中的所有元素
m.key_comp()返回“比较准则”
m.value_comp()返回针对value的“比较准则”,和key_comp()相同
m.count(val)返回key为val 的元素个数
m.find(val)返回key为val 的第一个元素,如果找不到就返回end()
m.lower_bound(val)返回key=val的第一个可安插位置,就是key>=val的第一个元素位置
m.upper_bound(val)返回key=val的最后一个可安插位置,就是key>val的第一个元素位置
m.equal_range(val)返回key=val可被安插的第一个位置和最后一个位置,就是key==val的元素区间
m1.swap(m2)交换m1和m2的数据
swap(m1, m2)交换m1和m2的数据
m.rbegin()返回反向iterator指向的反向迭代的第一个元素
m.rend()返回反向iterator指向的反向迭代最后一个元素的下一个位置
m.crbegin()返回const iterator反向迭代的第一个元素
m.crend()返回const iterator反向迭代的最后一个元素的下一个位置
m.insert(val)安插一个val拷贝,并返回新元素位置
m.insert(pos, val)安插val的拷贝,返回新元素位置,pos是个提示,指出安插动作的查找起点
m.insert(beg, end)将区间内所有元素拷贝到s,无返回值
m.insert(initlist)插入initlist所有元素,无返回值
m.emplace(args...)插入一个以args为初值的元素,并返回新元素位置
m.emplace_hind(pos, args...)插入一个以args为初值的元素,并返回新元素位置,pos是个提示,指出安插动作的查找起点
m.erase(val)移除与val相等的所有元素,返回被移除的元素个数
m.erase(pos)移除iterator位置pos上的元素,无返回值
m.erase(beg, end)移除区间内的所有元素,无返回值

3、无序集合unordered_set和无序字典unordered_map 

  • 无序容器的底层使用的是hash table,hash table所使用的解决碰撞的办法为拉链法,我们称hash table表格内的元素为桶(bucket),buckets的聚合体,则用vector完成,以便有动态扩充能力。
  • 每个bucket维护一个链表,每个hash code被关联至一个链表中,这个链表时属于单链表还是双链表,取决于实现,C++的标准只保证它们的iterator至少是个forward iterator。因此反向的iterator,包括rbegin()、rend()、crbegin()、crend()都不提供。
  • 使用hash table的优点是,如果拥有良好的hash策略,在安插、删除、查找元素时所用的时间为常量。
  • 使用hash table的容器不提供“直接元素访问的操作”。
  • 你可以指定bucket的最小数量。
  • 你可以(并且有时候必须)提供自己的哈希函数。哈希函数是个函数或者仿函数,它接收一个元素类型的value作为参数,并返回一个size_t的value。因此,bucket的当前数量并未被考虑。将其返回的值映射到合法的bucket索引内,是由容器内部完成的。
  • 你可以(并且有时候必须)提供自己的等价准则,它必须是个判断式。
  • 你可以指定一个最大负载系数(最大负载系数 = 总元素个数 / bucket的个数),一旦超过就会自动rehashing。
  • 你可以强迫rehashing,rehashing指的是重建hash table,即动态扩充bucket vector,并找出下一个新的并且足够大(大约两倍)的质数,检验旧表中的每个元素,计算其在新表中的位置,然后再插入到链表中。

(1)unordered容器的构造函数和析构函数如下:

Unord u默认构造函数,建立一个空的unordered容器
Unord u(bnum)建立一个空的unordered容器,至少使用bnum个bucket
Uord u(bnum, hf, cmp)建立一个空的unordered容器,至少使用bnum个bucket,以hf作为哈希函数cmp作为等价准则
Uord u(u2)复制构造函数,建立u2的拷贝
Uord u = u2复制构造函数,建立u2的拷贝
Uord u(beg, end)建立一个unordered容器,以[beg, end)元素作为初值
Uord u(beg, end, bnum)建立一个unordered容器,以[beg, end)元素作为初值,至少使用bnum个bucket
Uord u(beg, end, bnum, hf)建立一个unordered容器,以[beg, end)元素作为初值,至少使用bnum个bucket,以hf作为哈希函数
Uord u(beg, end, bnum, hf, cmp)建立一个unordered容器,以[beg, end)元素作为初值,至少使用bnum个bucket,以hf作为哈希函数cmp作为等价准则
Uord u(initlist)建立一个unordered容器,以initlist作为初值
Uord u = initlist建立一个unordered容器,以initlist作为初值
u.~Uord()销毁所有元素并释放内存

(2)Unordered容器Uord的所有可能类型如下:

unorderd_set<elem>一个unordered_set,使用默认的哈希函数和默认比较函数
unorderd_set<elem, hash>一个unordered_set,使用hash作为哈希函数,使用默认比较函数
unorderd_set<elem, hash, cmp>一个unordered_set,使用hash作为哈希函数,使用cmp比较函数
unordered_map<key, T>一个unordered_map,使用默认的哈希函数和默认比较函数
unordered_map<key, T, hash>一个unordered_map,使用hash作为哈希函数,使用默认比较函数
unordered_map<key, T, hash, cmp>一个unordered_map,使用hash作为哈希函数,使用cmp比较函数

(3)除了STL容器简介中的公共函数以外,unordered容器的其它函数 

u.hash_function()返回哈希函数
u.key_eq()返回比较函数
u.bucket_count()返回当前的bucket数量
u.bucket(val)返回val被找到的那个bucket编号
u.bucket_size(buckidx)返回第buckidx个bucket所含的元素个数
u.begin(buckidx)返回一个forward iterator,指向第buckidx个bucket中第一个元素
u.end(buckidx)返回一个forward iterator,指向第buckidx个bucket中最后个元素
u.cbegin(buckidx)返回一个const forward iterator,指向第buckidx个bucket中第一个元素
u.cend(buckidx)返回一个const forward iterator,指向第buckidx个bucket中最后个元素
u.max_bucket_count()返回bucket最大可能数量
u.load_factor()返回当前的负载系数
u.max_load_factor()返回当前最大的负载系数
u.max_load_factor(val)设定最大负载系数为val
u.rehash(bnum)将容器rehash,使其bucket个数至少为bnum
u.reserve(num)将容器rehash,使其空间至少可拥有num个元素
u1.swap(u2)交换u1和u2的数据
swap(u1, u2)交换u1和u2的数据
u.rbegin()返回反向iterator指向的反向迭代的第一个元素
u.rend()返回反向iterator指向的反向迭代最后一个元素的下一个位置
u.crbegin()返回const iterator反向迭代的第一个元素
u.crend()返回const iterator反向迭代的最后一个元素的下一个位置
u.insert(val)安插一个val拷贝,并返回新元素位置
u.insert(pos, val)安插val的拷贝,返回新元素位置,pos是个提示,指出安插动作的查找起点
u.insert(beg, end)将区间内所有元素拷贝到u,无返回值
u.insert(initlist)插入initlist所有元素,无返回值
u.emplace(args...)插入一个以args为初值的元素,并返回新元素位置
u.emplace_hind(pos, args...)插入一个以args为初值的元素,并返回新元素位置,pos是个提示,指出安插动作的查找起点
u.erase(val)移除与val相等的所有元素,返回被移除的元素个数
u.erase(pos)移除iterator位置pos上的元素,无返回值
u.erase(beg, end)移除区间内的所有元素,无返回值
u[key]安插一个带着key的元素——如果尚未存在于容器内。返回一个reference指向带着key的元素
u.at(key)返回一个reference指向带着key的元素

参考:《C++标准库》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C++中,map、unordered_mapset和unordered_set都是STL(标准模板库)中的容器。它们都用于存储一组数据,并提供了不同的功能和性能特点。 map是一个有序的关联容器,它使用红黑树实现,可以根据键值进行快速查找。map中的元素按照键值的大小进行排序,并且每个键值只能出现一次。\[1\]unordered_map是一个无序的关联容器,它使用哈希表实现,可以根据键值进行快速查找。unordered_map中的元素没有特定的顺序,并且每个键值只能出现一次。\[2\] set是一个有序的容器,它使用红黑树实现,可以存储不重复的元素。set中的元素按照值的大小进行排序,并且每个值只能出现一次。\[3\]unordered_set是一个无序的容器,它使用哈希表实现,可以存储不重复的元素。unordered_set中的元素没有特定的顺序,并且每个值只能出现一次。 在使用这些容器时,可以使用insert()函数插入元素,使用find()函数查找元素,使用erase()函数删除元素。此外,map和unordered_map还提供了count()函数来计算特定键值的出现次数。 总结来说,map和unordered_map适用于需要根据键值进行快速查找的场景,set和unordered_set适用于需要存储不重复元素的场景。具体选择哪个容器取决于你的需求和性能要求。 #### 引用[.reference_title] - *1* *3* [C++:map,unordered_map,set和unordered_set的用法和区别](https://blog.csdn.net/bryant_zhang/article/details/111600209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [初识C++之unordered_map与unordered_set](https://blog.csdn.net/Masquerena114514/article/details/129938734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值