面试题答案
一键面试迭代器失效原因
在std::set
中,当删除一个元素时,该元素对应的迭代器会失效。这是因为std::set
通常以红黑树等平衡二叉搜索树实现,删除操作会改变树的结构。一旦结构改变,指向被删除节点的迭代器就不再有效,继续使用会导致未定义行为。
避免迭代器失效及高效删除操作方法
- 使用erase返回的迭代器:
erase
成员函数会返回下一个有效的迭代器,利用这一点可以在删除元素后继续正确遍历。 - 逆序删除:从后往前删除元素,这样在删除当前元素时,前面的迭代器不会失效。但对于
std::set
,由于其内部有序,这种方法不太适用,所以主要采用第一种方法。
代码示例
#include <iostream>
#include <set>
int main() {
std::set<int> mySet = {1, 2, 3, 4, 5};
auto it = mySet.begin();
while (it != mySet.end()) {
if (*it % 2 == 0) { // 删除偶数
it = mySet.erase(it);
} else {
++it;
}
}
// 输出剩余元素
for (int num : mySet) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
优化策略解释
- 利用
erase
返回的迭代器:在while
循环中,当判断元素满足删除条件时,调用erase
并将返回值重新赋值给it
。这样it
就指向了下一个有效元素,保证了迭代的连续性。 - 减少不必要的操作:在不满足删除条件时,仅递增迭代器,避免了多余的函数调用,提高了效率。