unordered_multimap的insert问题

来源:互联网 发布:淘宝运营工资高吗 编辑:程序博客网 时间:2024/06/08 14:47

    在做一个编程练习的时候用到unordered_multimap关联容器,之所以想用unordered_multimap,是因为想要达到一种效果:首先要满足重复的关键字,其次要无序。在这两个条件的作用下,我想逐次插入多个元素,而且有重复元素。比如说,我新建一个空的unordered_multimap容器,然后我多次调用其insert()成员函数,插入多个元素,如下:

my_un_mul_map.insert({ 5, 2 });  my_un_mul_map.insert({ 4, 2 });  my_un_mul_map.insert({ 3, 2 });  my_un_mul_map.insert({ 1, 2 });  my_un_mul_map.insert({ 2, 2 });
    按照我的想法,现在my_un_mul_map中的元素顺序应该是:(1,2)、(5,2)、(4,2)、(3,2)、(1,2)(2,2)</span></strong>,因为是my_un_mul_map无序的,且可以允许重复关键字,所以每次insert操作都是直接插入到my_un_mul_map容器的末尾,而不用根据关键字的顺序进行排序,也就是说我的理解是unordered_multimap容器的insert操作跟vector容器的push_back操作时类似的,但是,上述理解是错误的

    上述插入完成之后,my_un_mul_map中的正确元素顺序(在VS2013中运行结果如下图)是:(1,2)、(1,2)、(5,2)、(4,2)、(3,2)、(2,2)也就是说尽管unordered_multimap能保证关键字无序,但是它还是把具有相同关键字的元素放在了一起。怎么说呢?这一点事实又打破了unordered_multimap容器的无序规则。这是为什么呢?究其原因,是因为无序关联容器中(包括unordered_multimap、unordered_multiset、unordered_map、unordered_set)其底层实现完全可以理解为一个Hash表,简单理解为是一个Hash数组(不知道这么理解对不对,但感觉是这个意思,也是最容易理解的),然后Hash数组中每个元素是一个“桶”,所谓“桶”,可以理解为其每个元素又是一个数组,而且每个桶里面保存的是具有相同关键字的元素,所以经过上述插入操作之后,my_un_mul_map中才出现了那样的元素顺序,因为尽管第二个(1、2)元素是最后插入到my_un_mul_map容器中的,但是结果Hash函数运算后,其插入到了原来已经存在的一个桶中了,所以就与最先插入的(1,2)元素放在了一起。


    针对上述测试与解释,然后去翻C++ Primer在P395(第五版)找到了无序关联容器的介绍无序关联容器在存储上组织为一组桶,每个桶保存零个或多个元素。无序容器使用一个哈希函数将元素映射到桶。如果容器运行重复关键字,则所有具有相同关键字的元素都保存在相同的桶中。可见,上述我自己的解释与理解应该是正确的,只是有一个不确定的是无序关联容器桶的个数是多少?Primer里面没有直接说明,但是介绍了关于无序关联容器的桶的接口,这里有两个接口:bucket_count()和max_bucket_count()分别为正在使用的桶的数目和容器能容纳的最多的桶的数目,这有点像vector的capacity和size的关系,这里任然在VS2010中进行测试无序关联容器桶的大小,结果如下:




    由测试结果可知,在VS2013环境中,无序关联容器的桶大小是8的n次方,而且bucket_count()和max_bucket_count()是相等的,通过这个测试,可以得出两个结论(1)无序关联容器中建立桶的大小与编译器的实现有关(这一点,可以点击这个链接查看点击打开链接);(2)无序关联容器底层的真正实现就是一个一维Hash数组,即每个桶都只保存一个元素,只是说具有相同关键字的元素组成相邻的桶。

原创粉丝点击