C++遍历删除map容器的注意事项

iterator erase(
    const_iterator Where);

iterator erase(
    const_iterator First,
    const_iterator Last);

size_type erase(
    const key_type& Key);

由于map只支持erase(const_iterator)或erase(const key_type &Key),即只能使用迭代器或键来删除pair元素。当遍历删除map中的某个元素后,指向那个元素的迭代器将因元素已删除而失效(地址不变,但没意义了,++或--都是没意义的),所以要想在erase掉某迭代器后还要使用该迭代器,必须在erase之前存储其++或--移位后(相对于map“容器”建立时的先后顺序)的迭代器,map是用哈希存储并寻址的,VScode监视map时展示出的“排列顺序”其实只是“map容器”加入元素的先后顺序,并不是地址顺序。删除掉一个中间元素后不会有vector连续容器那样的“移位”、“回填”的后台操作,map删除元素只是释放那个元素建立Hash映射时的堆内存,删除后再定义的迭代器再也不会指向那个元素,而删除前指向那个元素的迭代器的地址虽然不变但已经没意义了。

举个例子:原始map容器各元素地址:

首先再次编译以下:

这里可以很直观地观察到map容器是采用哈希存储的,map元素的地址不连续,并且再次编译后各元素地址的低4个16进制位(对应低位2个字节,测试程序是32位程序,共4字节内存地址可用)保持不变,这其实就是用哈希计算出的pair元素地址。

C++基础-map与unordered_map - 知乎

map是基于红黑树实现。红黑树作为一种自平衡二叉树,保障了良好的最坏情况运行时间,即它可以做到在O(log n)时间内完成查找,插入和删除,在对单次时间敏感的场景下比较建议使用map做为容器。比如实时应用,可以保证最坏情况的运行时间也在预期之内。


unordered_map是基于hash_table实现,一般是由一个大vector,vector元素节点可挂接链表来解决冲突来实现。hash_table最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。

删除第一个元素后,原来指向第一个元素的迭代器失效,虽然地址不变,但已经没意义了。而删之前++指向后面元素的迭代器保持自己的指向,要和vector顺序容器的“批量移位”、“批量回填”区别开!。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,可以使用迭代器来遍历set容器map容器。下面是遍历这两种容器的示例代码: 遍历set容器: ```cpp std::set<int> mySet = {1, 2, 3, 4, 5}; // 使用迭代器遍历set容器 for (std::set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) { int element = *it; // 获取当前元素的值 // 执行操作,例如打印或处理元素 } ``` 遍历map容器: ```cpp std::map<int, std::string> myMap = {{1, "apple"}, {2, "banana"}, {3, "cherry"}}; // 使用迭代器遍历map容器 for (std::map<int, std::string>::iterator it = myMap.begin(); it != myMap.end(); ++it) { int key = it->first; // 获取当前键的值 std::string value = it->second; // 获取当前值的值 // 执行操作,例如打印或处理键值对 } ``` 另外,C++11引入了范围-based for循环,也可以用于遍历set容器map容器遍历set容器: ```cpp std::set<int> mySet = {1, 2, 3, 4, 5}; // 使用范围-based for循环遍历set容器 for (const auto& element : mySet) { // 执行操作,例如打印或处理元素 } ``` 遍历map容器: ```cpp std::map<int, std::string> myMap = {{1, "apple"}, {2, "banana"}, {3, "cherry"}}; // 使用范围-based for循环遍历map容器 for (const auto& pair : myMap) { int key = pair.first; // 获取当前键的值 std::string value = pair.second; // 获取当前值的值 // 执行操作,例如打印或处理键值对 } ``` 请注意,在遍历map容器时,使用`pair.first`获取键,使用`pair.second`获取值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值