【发布时间】:2017-08-06 23:14:04
【问题描述】:
我正在考虑在二叉搜索树中实现删除。我知道 std::map 和 std::set 通常实现为 RBTree。但无论如何,如果它是一些 BST,那么在擦除/删除具有 2 个子节点的节点时,我们通常将其与其后继(或前任)交换。许多教科书表明这只是复制继任者的关键和价值。但是这个副本不是透明的。例如,如果该值是另一个我有未明确迭代器的容器,那么删除一些 OTHER 键,值现在可以使我对一个我没有明确更改的容器所拥有的迭代器无效。而不是复制键值,我们可以将后继节点重新链接到应该删除的节点所在的树中。这将保持节点的状态。
假设我有一张矢量地图:
std::map<int, vector<int> > mymap;
// Add root
mymap.insert(make_pair(2, vector<int>()));
// Add left child
mymap.insert(make_pair(1, vector<int>()));
// Add right child
mymap.insert(make_pair(3, vector<int>()));
mymap[3].push_back(10);
// I get an iterator to the vector stored in the node with key=3
vector<int>::iterator it = mymap[3].begin();
// I now remove element 2 from the map.
mymap.erase(2);
// If the successor's (i.e. 3's) key,value were *copied* to 2's node
// and then 3's node was deleted this would invalid iterators
vector<int>::iterator it2 = mymap[3].begin();
// These could/should be different if remove copied the successor
cout << &*it << " " << &*it2 << endl;
当然,包含 3 的节点可以在树中“重新链接”来代替 2 的节点并删除 2 的节点。这将保持键值的正确状态。
我编写了这个测试用例,它似乎是重新链接而不是复制。该行为是否在任何地方定义?
类似地,如果我有一个向量向量(即向量 > 并且我持有一个指向“内部”向量之一中的元素的迭代器,但是外部向量由于插入另一个向量而调整大小,那么即使我的迭代器无效我没有从技术上修改那个内部向量。无效的“传递”属性是在某处拼写出来的,还是“明显的”/“暗示的”,我只是玩得很慢?
【问题讨论】:
标签: c++ dictionary iterator binary-search-tree