这里简单学习一下STL关联容器,主要是map、multimap、set、multiset以及unordered_map。前四个底层实现都是利用红黑树实现的,查找算法时间复杂度为\(O(log(n))\),而unordered_map从名字上就知道是无序容器,其实现原理类似哈希表,查找算法时间复杂度\(O(1)\)。

set、multiset、map、multimap

set容器是一个存储有序唯一元素的数据结构。不允许有重复元素。其底层实现为红黑树。multiset原理与set相同,不同的是允许有重复元素存在。

map映射是可以用任何类型的数据作为索引的表,不允许有重复元素,其实现原理与set类似,底层都是红黑树。multimap允许有重复元素存在。

template<typename _Key, typename _Compare = std::less<_Key>,typename _Alloc = std::allocator<_Key> >
class set
public:
typedef _Key key_type;
typedef _Key value_type; // 与map不同
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Alloc allocator_type; private:
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Key_alloc_type> _Rep_type; _Rep_type _M_t; // Red-black tree representing set. 红黑树 typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits; #if __cplusplus > 201402L
using node_type = typename _Rep_type::node_type;
using insert_return_type = typename _Rep_type::insert_return_type;
#endif

map与set其实现原理类似,不同的是map中每个元素是std::pair对。

template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,typename _Alloc=std::allocator<std::pair<const _Key, _Tp> > >
class map {
public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type; // 其值是pair对的形式存储
typedef _Compare key_compare; // RB-tree,需要对元素进行比较
typedef _Alloc allocator_type; private:
/// This turns a red-black tree into a [multi]map.
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<value_type>::other _Pair_alloc_type;
typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Pair_alloc_type> _Rep_type; /// The actual tree structure.
_Rep_type _M_t; // 底层实现RB-tree typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits; public:
// 重载[]
mapped_type& operator[](const key_type& __k) {
// concept requirements
__glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>)
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
#if __cplusplus >= 201103L
__i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, std::tuple<const key_type&>(__k),
std::tuple<>());
#else
__i = insert(__i, value_type(__k, mapped_type()));
#endif
return (*__i).second;
}
}

其他具体实现细节这里不再列出,只要懂红黑树的原理,很容易理解。

unordered_map

这个实现与map不同,其底层是哈希表,理解了哈希表就很容易理解unordered_map。

template<class _Key, class _Tp,class _Hash = hash<_Key>,class _Pred = std::equal_to<_Key>,class _Alloc=std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map {
typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
_Hashtable _M_h; // 可以看到底层实现是哈希表 public:
// typedefs:
//@{
/// Public typedefs.
typedef typename _Hashtable::key_type key_type;
typedef typename _Hashtable::value_type value_type;
typedef typename _Hashtable::mapped_type mapped_type;
typedef typename _Hashtable::hasher hasher;
typedef typename _Hashtable::key_equal key_equal;
typedef typename _Hashtable::allocator_type allocator_type;
//@} #if __cplusplus > 201402L
using node_type = typename _Hashtable::node_type;
using insert_return_type = typename _Hashtable::insert_return_type;
#endif

STL关联容器的更多相关文章

  1. STL关联容器的基本操作

    关联容器 map,set map map是一种关联式容器包含 键/值 key/value 相当于python中的字典不允许有重复的keymap 无重复,有序 Map是STL的一个关联容器,它提供一对一 ...

  2. STL关联容器总结

    有序的都不带unordered,即如下: set multiset map multimap 其中带multi的表示关键字可以重复 无序的带unordered,如下: unordered_map un ...

  3. STL关联容器值hashtable

    hashtable(散列表)是一种数据结构,在元素的插入,删除,搜索操作上具有常数平均时间复杂度O(1); hashtable名词 散列函数:负责将某一元素映射为索引. 碰撞(collision):不 ...

  4. STL 笔记(二) 关联容器 map、set、multimap 和 multimap

    STL 关联容器简单介绍 关联容器即 key-value 键值对容器,依靠 key 来存储和读取元素. 在 STL 中,有四种关联容器,各自是: map 键值对 key-value 存储,key 不可 ...

  5. STL List容器

    转载http://www.cnblogs.com/fangyukuan/archive/2010/09/21/1832364.html 各个容器有很多的相似性.先学好一个,其它的就好办了.先从基础开始 ...

  6. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  7. STL的基本使用之关联容器:map和multiMap的基本使用

    STL的基本使用之关联容器:map和multiMap的基本使用 简介 map 和 multimap 内部也都是使用红黑树来实现,他们存储的是键值对,并且会自动将元素的key进行排序.两者不同在于map ...

  8. STL的基本使用之关联容器:set和multiSet的基本使用

    STL的基本使用之关联容器:set和multiSet的基本使用 简介 set 和 multiSet 内部都是使用红黑树来实现,会自动将元素进行排序.两者不同在于set 不允许重复,而multiSet ...

  9. STL之关联容器---set, mutilset, map, mutilmap

    STL的容器分为序列容器和关联容器.它们所表达的数据结构各有不同: 序列容器:vector(变长数组), list(链表), queue(队列), heap(堆算法)等 关联容器:set/mutils ...

随机推荐

  1. C# 数据操作系列 - 7. EF Core 导航属性配置

    在上一篇,大概介绍了Entity Framework Core关于关系映射的逻辑.在上一篇中留下了EF的外键映射没有说,也就是一对一,一对多,多对一,多对多的关系等.这一篇将为大家细细分析一下,如何设 ...

  2. 题解 P4296 【[AHOI2007]密码箱】

    由题意有 \(x^2\equiv 1\;mod\;n\) 对题目的公式进行变形 \(x^2-1=k\times n\) \((x+1)(x-1)=k\times n\) 由唯一分解定理,我们构造\(a ...

  3. spring中<context:property-placeholder/>一个坑

    <context:property-placeholder location="classpath:db.properties" ></context:prope ...

  4. mysql全方位知识大盘点

    一.mysql都有哪些存储引擎?各自的特点是什么? 引擎 事务 锁 主键 索引 外键 数据结构 适用场景 InnoDB 支持 行锁.表锁 必须有主键,没有设置会自动创建 主键索引和数据在一起,其他索引 ...

  5. 解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)

    一.问题 有时候我们登录Mysql输入密码的时候,会出现这种情况 mysql -u root -p Enter Password > '密码' 错误:ERROR 1045 (28000): Ac ...

  6. html浏览器高度和宽度和其他dom获取

    1.获取网页可见区域的宽度:document.body.clientWidth ; 2.获取网页可见区域的高度:document.body.clientHeight; 3.获取 网页可见区域宽:doc ...

  7. pytest跳过指定的测试或模块

    参考Allure官方文档,pytest官方文档 实现setup/teardown 1.运行带指定标记的测试 @pytest.mark.tags ,这里的tags可以自定义 命令行执行:pytest - ...

  8. web自动化之浏览器的窗口切换

    from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...

  9. 【Mathtype】安装Mathtype后,word无法粘贴的问题

    Win10安装mathtype后,word工具栏中自动添加mathtype的选项(mathtype为了使用户更加方便使用,故自动添加),但是却导致word无法粘贴.如何解决该问题? [方案1]官网描述 ...

  10. 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)

      2020/4/30   15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...