C++ STL无序容器种类

  • 无序容器是 C++ 11 标准才正式引入到 STL 标准库中的,这意味着如果要使用该类容器,则必须选择支持 C++ 11 标准的编译器
  • 以 map 和 unordered_map 为例,其实它们仅有一个区别,即 map 容器内存会对存储的键值对进行排序,而 unordered_map 不会。

unordered_map

几种初始化方式:

  1. std::unordered_map<std::string, std::string> umap;
  2. std::unordered_map<std::string, std::string> umap{
    {"Python教程","http://c.biancheng.net/python/"},
    {"Java教程","http://c.biancheng.net/java/"},
    {"Linux教程","http://c.biancheng.net/linux/"} };
  3. std::unordered_map<std::string, std::string> umap2(umap);
  4. /传入 2 个迭代器,
    std::unordered_map<std::string, std::string> umap2(++umap.begin(),umap.end());

unordered_multimap

  • 具体用法同上
  • STL 标准库中实现 unordered_multimap 容器的模板类并没有定义在以自己名称命名的头文件中,而是和 unordered_map 容器一样,定义在<unordered_map>头文件,且位于 std 命名空间中

unordered_set

几种初始化方式:

  1. std::unordered_setstd::string uset;
  2. std::unordered_setstd::string uset{ "http://c.biancheng.net/c/",
    "http://c.biancheng.net/java/",
    "http://c.biancheng.net/linux/" };
  3. std::unordered_setstd::string uset2(uset);
  4. //传入 2 个迭代器,
    std::unordered_setstd::string uset2(++uset.begin(),uset.end());

unordered_multiset

  • 具体用法同上
  • STL 标准库中实现 unordered_multiset容器的模板类并没有定义在以自己名称命名的头文件中,而是和 unordered_set容器一样,定义在<unordered_set>头文件,且位于 std 命名空间中

无序容器底层实现机制(STL采用的)

  • 线性探测法(二次探测法),用array容器实现的解法,很明显,这种方式没有被STL采用

  • 无序容器的底层实现都采用的是哈希表存储结构

  • 用“链地址法”(又称“开链法”)解决数据存储位置发生冲突的哈希表

  • STL 标准库通常选用 vector 容器存储各个链表的头指针。

  • 在 C++ STL 标准库中,将图 1 中的各个链表称为桶(bucket),每个桶都有自己的编号(从 0 开始)。当有新键值对存储到无序容器中时,整个存储过程分为如下几步:
    1.将该键值对中键的值带入设计好的哈希函数,会得到一个哈希值(一个整数,用 H 表示);0
    2.将 H 和无序容器拥有桶的数量 n 做整除运算(即 H % n),该结果即表示应将此键值对存储到的桶的编号;
    3.建立一个新节点存储此键值对,同时将该节点链接到相应编号的桶上。

  • 负载因子 = 容器存储的总键值对 / 桶数
    该属性同样适用于无序容器,用于衡量容器存储键值对的空/满程序,即负载因子越大,意味着容器越满,即各链表中挂载着越多的键值对,这无疑会降低容器查找目标键值对的效率;反之,负载因子越小,容器肯定越空,但并不一定各个链表中挂载的键值对就越少

posted on 2021-04-11 17:26  逆流而上の鱼  阅读(98)  评论(0编辑  收藏  举报