这里简单学习一下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. java -> 异常类与自定义异常

    异常 什么是异常?Java代码在运行时期发生的问题就是异常. 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 异常的继承体 ...

  2. 2018-06-17 js数组

    数组的定义:① var arr=new Array(xx,xx,xx); ②var arr=[yy,yy,,yy]; 数组的查看:arr[x]; 数组的修改:arr[x]=xx; 数组的遍历:①for ...

  3. .Net Core3.0 WebApi 项目框架搭建 三:读取appsettings.json

    .Net Core3.0 WebApi 项目框架搭建:目录 appsettings.json 我们在写项目时往往会把一些经常变动的,可能会变动的参数写到配置文件.数据库中等可以存储数据且方便配置的地方 ...

  4. 【图机器学习】cs224w Lecture 10 - PageRank

    目录 PageRank Problems Personalized PageRank 转自本人:https://blog.csdn.net/New2World/article/details/1062 ...

  5. mysql小白系列_14 线上故障分析与排错

    1.重现故障5---线上执行update报错,并处理.(表结构和UPDATE语句自己构造,请给出详细步骤) 1)update故障出现ERROR 1206 (HY000): The total numb ...

  6. drf 生命周期

    1) 根据应用中urls.py,走as_view方法,但是视图类没有该方法,所以请求走的是APIView的as_view方法 2) 在APIView的as_view调用父类(django原生View) ...

  7. iOS开发常用技能点(持续更新中。。。)

    1,以屏幕原点开始布局  (默认从导航栏原点布局) self.extendedLayoutIncludesOpaqueBars = YES;   2,向button发送点击事件 [self.playB ...

  8. vue2.0 axios前后端数据处理

    目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目都会使用 Vuex 来管理数据. 前言: 使用 cnpm 安装 axios cnpm install axios -S ...

  9. python脚本实现接口自动化轻松搞定上千条接口用例

    接口自动化目前是测试圈主流的一个话题,我也在网上搜索了很多关于自动化的关键词,大多数博主分享的python做接口自动化都是以开源的框架,比如:pytest.unittest+ddt(数据驱动) 最常见 ...

  10. spring的动态代理实现

    Host.java package cn.zys.dynamiproxy; public class Host implements Rent{ public void rent(){ System. ...