STL-map中的插入操作详解

本文详细解读了C++ map容器的使用方法,包括如何使用map进行键值对的插入、查找及替换操作。通过分析源码,揭示了内部实现的红黑树结构以及[]操作的原理,帮助开发者深入了解map容器的工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,我们可以如下使用map:

//#include <map>

map<string, int> simap;
map[string("hou")] = 1;
map[string("hou")] = 2;
pair<string, int> value(string("ha"), 5);
simap.insert(value);

先看insert操作的源码:

 pair<iterator,bool> insert(const value_type& x) 
 { return t.insert_unique(x); }

其中,value_type是一个pair:

typedef pair<const Key, T> value_type;

因此上述的插入操作是向map中插入一个pair,它包含键和值。

[]操作在map中不包含键值的时候会插入键值,当包含键值时会替换相应的键值。这里要说的是insert_unique(),它是map底层使用的红黑树中的插入操作,源码如下:

template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool>
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)
{
  link_type y = header;
  link_type x = root();
  bool comp = true;
  while (x != 0) {
    y = x;
    comp = key_compare(KeyOfValue()(v), key(x));
    x = comp ? left(x) : right(x);
  }
  iterator j = iterator(y);   
  if (comp)
    if (j == begin())     
      return pair<iterator,bool>(__insert(x, y, v), true);
    else
      --j;
  if (key_compare(key(j.node), KeyOfValue()(v)))//插入的值不与既有节点值重复
    return pair<iterator,bool>(__insert(x, y, v), true);
  return pair<iterator,bool>(j, false);

从上述代码中我们可以看出,unique_insert()只会在键不存在的时候才会插入成功(pair的第二个值为true)。


接下来分析[]操作:

 T& operator[](const key_type& k) {
    return (*((insert(value_type(k, T()))).first)).second;

k是键,首先构造一个pair:

value_type(k, T())

然后将这个pair插入到红黑树中:

insert(value_type(k, T()))

插入代码在之前已经说明过。它是唯一性的插入,即如果已经存在键,那么不会插入,返回的pair中的第二个元素是false

接下来取返回pair的第一个元素,也就是个迭代器:

(insert(value_type(k, T()))).first

取迭代器指向节点的值:

*((insert(value_type(k, T()))).first))

该值实际上就是一个pair,这跟上面说的pair不一样。此处的pair是一个键值对。

接下来取出它的值:

(*((insert(value_type(k, T()))).first)).second

最后,返回该值的引用即可。

这就是map中的下标操作,这也就说明了文章刚开始时候代码能运行的原因。

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值