multiset和set,map和multimap的区别

一、set和multiset的差异和相同

set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。
set不可以直接存取元素。(不可以使用at.(pos)与[]操作符)。
multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。
不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。

set/multiset对象的默认构造
set setInt; //一个存放int的set容器。
set setFloat; //一个存放float的set容器。
set setString; //一个存放string的set容器。
multiset mulsetInt; //一个存放int的multi set容器。
multi set multisetFloat; //一个存放float的multi set容器。
multi set multisetString; //一个存放string的multi set容器。
set的插入与迭代器
set.insert(elem); //在容器中插入元素。
set.begin(); //返回容器中第一个数据的迭代器。
set.end(); //返回容器中最后一个数据之后的迭代器。
set.rbegin(); //返回容器中倒数第一个元素的迭代器。
set.rend(); //返回容器中倒数最后一个元素的后面的迭代器。

原文链接:https://blog.csdn.net/weixin_43916755/article/details/95058079  

二、关联容器和map容器概述

map容器是关联容器的一种。在关联容器中,对象的位置取决于和它关联的键的值。键可以是基本类型也可以是类类型。关联容器是与非关联容器(顺序容器)相对应的,顺序容器中元素的位置不依赖于元素的值,而是和该元素加入容器时的位置有关。关联容器的类型有下面八种:

按关键字有序保存元素
map                      关联数组;保存关键字-值对
set                      关键字即值,只保存关键字的容器
multimap                 关键字可以重复出现的map
multiset                 关键字可以重复出现的set
 
无序关联容器
unordered_map            用哈希函数组织的map,无序
unordered_set            用哈希函数组织的set,无序
unordered_multimap       哈希组织的map;关键字可以重复
unordered_multiset       哈希组织的set,关键字可以重复

map容器有四种,每一种都是由类模板定义的。所有类型的map容器保存的都是键值对的元素。map容器的元素是pair类型的对象,这种对象封装了一个T类型的对象和一个与其关联的K类型的键。pair元素中的键是const,因为修改键会扰乱容器中元素的顺序。每种map容器的模板都有不同的特性:

1、map容器:map的底层是由红黑树实现的,红黑树的每一个节点都代表着map的一个元素。该数据结构具有自动排序的功能,因此map内部的元素都是有序的,元素在容器中的顺序是通过比较键值确定的。默认使用 less 对象比较。

2、multimap容器:与map容器类似,区别只在于multimap容器可以保存键值相同的元素。

3、unordered_map容器:该容器的底层是由哈希(又名散列)函数组织实现的。元素的顺序并不是由键值决定的,而是由键值的哈希值确定的,哈希值是由哈希函数生成的一个整数。利用哈希函数,将关键字的哈希值都放在一个桶(bucket)里面,具有相同哈希值的放到同一个桶。unordered_map内部元素的存储是无序的,也不允许有重复键值的元素,相当于java中的HashMap。

4、unordered_multimap容器:也可以通过键值生成的哈希值来确定对象的位置,但是它

允许有重复的元素。

map和multimap容器的模板都定义在map头文件中,unordered_map和unordered_multimap容器的模板都定义在unordered_map头文件中中。

multi前缀表明键值不必唯一,但是如果没有这个前缀,键值必须唯一。
unordered前缀表明容器中元素的位置是通过其键值所产生的哈希值来决定的,而不是通过比较键值决定的,即容器中的元素是无序的。如果没有这个前缀,则容器中元素是由比较键值决定的,即有序。

 map容器

下图展示了一个用名称作为键值 map容器,对象是整数,用来表示年龄。

前面讲过map容器的底层是由红黑树(一种非严格意义上的平衡二叉树)实现的,元素检索的时间复杂度是O(logN),相比于顺序检索的线性时间复杂度还是很快的。

2.1 map的创建以及初始化列表

map类模板有四个类型参数,但是一般只需要指定前两个模板参数的值。第一个是键值的类型,第二个是所保存对象的类型。我们通常所用的一种构造一个map对象的方法是:

Map mapStudent;

当初始化一个map时,必须提供关键字类型和值类型。我们将每个关键字-值对包围在花括号中: {key,value} 来指出它们一起构成了map中的一个元素。初始化列表有两种方式:


map authors = { {"Joyce", "James"},
                                {"Austen", "Jane"},
                                {"Dickens", "Charles"} };

性。

2.2 map容器的一般常用属性(方法)

size         返回有效元素个数
max_size     返回容器支持的最大元素个数
empty        判断容器是否为空,为空是返回true,否则返回false
clear        清空map容器
2.3 插入数据

在构造map容器后,我们就可以往里面插入数据了。这里讲三种常见的数据插入方法。

第一种:用insert函数插入pair数据

map mapStudent;//创建map
mapStudent.insert(pair("student_one", 22));
mapStudent.insert(pair("student_two", 25));
mapStudent.insert(pair("student_three", 21));
 
或者使用make_pair
map mapStudent;
mapStudent.insert(make_pair("student_one", 22));
mapStudent.insert(make_pair("student_two", 25));
mapStudent.insert(make_pair("student_three", 21));

第二种:用insert函数插入value_type数据

map mapStudent;//创建map
mapStudent.insert(map::value_type("student_one", 22));
mapStudent.insert(map::value_type("student_two", 25));
mapStudent.insert(map::value_type("student_three", 21));

第三种:用数组方式插入数据

map mapStudent;//创建map
mapStudent["student_one"] = 22;
mapStudent["student_two"] = 25;
mapStudent["student_three"] = 21;

第四种:用emplace函数插入数据

map mapStudent;
mapStudent.emplace("student_one", 22);
mapStudent.emplace("student_two", 25);
mapStudent.emplace("student_three", 21);

这几种插入方法的区别:

  • 用insert函数的效果是一样的,在数据的插入上涉及到集合的唯一性这个概念,即当map中有某个关键字时,insert操作是失败的。
  • emplace插入效果跟insert效果一样。
  • 用数组方式插入数据就不同,它可以覆盖以前该关键字对应的值。

原文链接:C++ map容器和multimap容器(STL map容器)_Magnum的博客-CSDN博客_c++ multimap


 

你可能感兴趣的:(c++,数据结构,b树)