C++容易忘记的知识点——map和set(六)

来源:互联网 发布:移动运营商数据分析 编辑:程序博客网 时间:2024/06/01 09:19

map

    map通常称为关联数组,每个元素key/value pair,每个key只能出现一次,不允许重复。而multimap是允许元素拥有相同的key。

map的特点

  1. 不可以直接改变元素的key,要修改元素的key,必须先移出该key的元素,然后插入新的key/value的元素。
  2. map中的元素是根据指定的比较函数按键值排序。
  3. 每个元素具有唯一的键值。
  4. 支持快速查找,查找的复杂度基本是log(N)。
  5. 快速插入,删除和修改value值。

map的初始化

//这里的value_type是pair<const char,int>,key_type是char,mapped_type(每个关键字关联的类型)是intmap<char,int>  first;    //默认构造函数map<char,int,comp> first1;  //构建空的map容器,comp是key_compare类型。按照comp对key进行排序/*comp的基本构建法struct comp{    bool operator()(const char& lhs,const char &rhs)const    { return lhs>rhs;}};*/map<char,int>  second(first);  //复制构造函数map<char,int>  third(second.begin(),second.end());  //范围构造函数map<char,int,comp> third1(second.begin(),second.end());   map<char,int> fourth(std::move(third));   //移动构造函数map<char,int> fifth{{'a',1},{'b',2},{'c',3}};  //初始化列表进行初始化map<char,int> fifth1={{'a',1},{'b',2},{'c',3}}; 

map相关的函数

这里写图片描述

pair类型

    pair定义在utility中,一个pair保存两个数据成员,所以创建时,必须提供连个类型名。

//pair的初始化,这里假设第一个类型名为string,第二个类型名为intpair<string,int> p1;           //默认构造函数pair<string,int> p2(p1);    //复制构造函数pair<string,int> p3("aaaa",5);  //用给定值初始化pair<string,int> p4=p3;                     //利用赋值操作符pair<string,int> p5=make_pair("bbbb",4);   //利用make_pair//其他常用的操作p.first           //返回p的名为first的数据成员p.second          //返回p的名为second的数据成员p.swap(p1);       //交换p和p1的frist和secondswap(p,p1);

set

    set是关键字的简单集合,元素依据其value自动排序,每个元素只出现一次,不允许重复。而multiset与它的唯一差别是元素可以重复。

set的特点

  1. set容器中的键值,不可直接修改,直接修改将会报纸set的内部结构(平衡二叉树)不平衡。
  2. 根据关键字可以快速读取数据。
  3. 每个元素都是唯一的。

set的初始化

//默认构造函数set<int> s1;set<int,comp> s2;  //comp是key_compare类型,构造方法见map的初始化,若没有comp,默认是lessset<int> s3(b,e)   //b,e是std::set<int>::iterator,将[b,e)之间的值赋给setset<int> s4(s3);    //赋值构造函数set<int> s5(move(s4));   //移动构造函数set<int>  s6{1,2,3,4,5};   //列表初始化

set的操作

操作

map和set的常问的问题

为何map和set的插入删除效率比用其他序列容器高?
    因为对于关联容器来说,不需要做内存拷贝和内存移动。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。插入和删除就是指针换来换去,和内存移动没有关系。
为何每次insert之后,以前保存的iterator不会失效?
    iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对与vector来说,vector每次插入和删除,指针都有可能会失效,比如:当该内存块不够它扩容时,它会申请其它内存块,此时指针会失效!
当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何?
    STL的优势并不在于算法,而在于内存碎片。如果你需要经常自己去new一些节点,当节点特别多,而且进行频繁的删除和插入的时候,内存碎片就会存在,而STL采用自己的Allocator分配内存,以内存池的方式来管理这些内存,会大大减少内存碎片,从而会提升系统的整体性能。当时间运行很长时间后(例如后台服务程序),map的优势就会体现出来。从另外一个方面讲,使用map会大大降低你的编码难度,同时增加程序的可读性。学习STL map, STL set之数据结构基础看来是很有必要的。