没有父指针的std :: map?

时间:2018-02-20 04:53:39

标签: c++ c++17

libstdc ++,作为一个例子,使用红色黑色二叉树实现std :: map,其中节点中有父指针。这意味着迭代器只能是指向节点的指针。

标准库是否可以实现std :: map而不在节点中存储父指针?我认为这意味着迭代器需要包含一堆父指针,因此需要动态分配一个对数量的内存。这会违反迭代器的标准性能限制吗?不会有父指针违反接口其余部分的任何其他性能约束吗?

C ++ 17中的新节点填充/接口怎么样?

2 个答案:

答案 0 :(得分:14)

他们可能不会这样做。 std::map保证从中删除键值对不会使除被删除对之外的任何迭代器无效。

如果迭代器将存储一堆父项,并且父项被删除,那么这也将使这些迭代器无效。保证将不再适用。

答案 1 :(得分:1)

有可能吗?可能:-)这是个好主意吗?几乎肯定不是。 大多数事情是可能的,如果你投入更多的存储空间或速度: - )

就刚刚摆脱父指针而言,可以,例如在地图中维护一个单调值,每次更改地图结构时都会递增。实质上,它是地图结构的版本标识符。因此,在地图中添加或删除元素会增加此值,而仅更改地图中的数据则不会。

然后迭代器将包含:

  • 指向地图本身的指针(获取当前版本);
  • 指针堆栈;和
  • 与上次创建堆栈时匹配的版本。

这个想法基本上是在使用迭代器做任何事情之前,检测地图版本何时与迭代器版本不同,如果是,则重建堆栈并更新迭代器版本,然后继续执行任何操作&# 39;重新尝试表演。

现在,虽然这使得可以在没有父指针的情况下进行迭代,但遗憾的是它违反了迭代器的一些其他要求,例如能够在恒定时间内执行它们。必须根据地图中的数据重建数据结构的任何将违反该限制。

在任何情况下,如果有更好的父指针,那么任何心智正常的人都不会实施这样一个可怕的方案,但这里的目的是只是为了表明它可能。

因此我的建议是坚持使用父指针。使用这样的父指针使得查找下一个/前一个元素的过程非常简单,基于迭代器中的当前项。