c++ - 在 std::map 中更改元素键的最快方法是什么

标签 c++ performance dictionary binary-tree std

我理解为什么一个人不能这样做(再平衡和其他东西):

iterator i = m.find(33);

if (i != m.end())
  i->first = 22;

但到目前为止,更改键的唯一方法(我知道)是从树中删除节点,然后用不同的键插入值:

iterator i = m.find(33);

if (i != m.end())
{
  value = i->second;
  m.erase(i);
  m[22] = value;
}

这对我来说似乎相当低效,原因有很多:

  1. 遍历树三次(+平衡)而不是两次(+平衡)

  2. 值的另一个不必要的拷贝

  3. 不必要的释放,然后重新分配树内的节点

我发现分配和释放是这三个中最差的。我错过了什么还是有更有效的方法来做到这一点?

我认为,理论上应该是可能的,所以我认为改变不同的数据结构是不合理的。这是我想到的伪算法:

  1. 在树中找到我要更改其键的节点。

  2. 如果从树中分离(不要释放)

  3. 再平衡

  4. 更改分离节点内的键

  5. 将节点重新插入树中

  6. 再平衡

最佳答案

在 C++17 中,新的 map::extract功能可让您更改 key 。
示例:

std::map<int, std::string> m{ {10, "potato"}, {1, "banana"} };
auto nodeHandler = m.extract(10);
nodeHandler.key() = 2;
m.insert(std::move(nodeHandler)); // { { 1, "banana" }, { 2, "potato" } }

关于c++ - 在 std::map 中更改元素键的最快方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5743545/

相关文章:

python - Pandas 如果完整的字符串包含在另一个 Pandas 数据框中

python - 如果列表中存在值,则返回键(来自字典)

c++ - Google 测试中的 "Assert and return"宏?

c++ - 在 DLL 构建期间包含特定文件时 LoadLibrary 失败

java - Java DB Derby Blob 和删除的性能问题

javascript - $rootScope.$new 与 $scope.$new 的性能

python - 如何有效地将字典的条目转换为数据框

c++ - 为什么选择 for (;;){} 而不是 while(1)?

c++ - 为什么我们需要将函数标记为 constexpr?

performance - 是否可以改善 conda 环境的激活时间?