自定义List erase后迭代器重构及循环删除异常问题咨询
解决List erase后迭代器失效及循环删除的问题
首先来说erase后迭代器重构的实现思路:当你调用erase(it)删除迭代器指向的节点时,原来的迭代器it会因为指向的内存被释放(或脱离链表)而失效,所以我们需要让List::erase方法返回指向被删除节点的下一个节点的有效迭代器,这样就能直接用返回值更新迭代器,避免失效问题。
1. 修改List的erase方法实现
你需要在List.h里修改erase的模板实现,让它返回正确的迭代器:
template<typename T> typename List<T>::Iterator List<T>::erase(Iterator it) { // 先保存当前节点的下一个节点,避免删除后找不到 Node<T>* next_node = it.node_->next; // 执行删除节点的逻辑:调整前后节点的指针,释放当前节点内存 if (it.node_->prev) { it.node_->prev->next = next_node; } else { // 如果删除的是头节点,更新链表的head head_ = next_node; } if (next_node) { next_node->prev = it.node_->prev; } else { // 如果删除的是尾节点,更新链表的tail tail_ = it.node_->prev; } delete it.node_; size_--; // 返回指向next_node的迭代器 return Iterator(next_node); }
这里的关键是在删除节点前先缓存下一个节点,然后构造并返回指向该节点的迭代器,这样调用方就能用这个返回值更新自己的迭代器,保证后续操作的有效性。
2. 解决循环删除时的"隔个元素"问题
你现在的循环写法:
for (Util::List<int>::Iterator it = list.begin(); it != list.end(); ++it) { it = list.erase(it); }
出现删除后剩下1 3 5 7 9的原因是:erase已经返回了下一个节点的迭代器,但循环末尾又执行了++it,相当于连续跳了两步,自然就跳过了中间的元素。
标准库的std::list::erase也是同样的行为:它会返回指向被删除元素的下一个元素的迭代器,所以正确的循环写法应该去掉循环里的++it,或者调整循环逻辑:
正确写法1:删除所有元素
auto it = list.begin(); while (it != list.end()) { it = list.erase(it); }
这样每次erase后,it直接指向了下一个节点,循环继续判断直到end,就能删除所有元素。
正确写法2:条件删除(只删符合条件的元素)
auto it = list.begin(); while (it != list.end()) { if (/* 满足删除条件的判断 */) { it = list.erase(it); } else { ++it; // 只有不删除的时候才递增迭代器 } }
这样就不会出现跳过元素的问题,和标准库list的使用方式完全一致。
内容的提问来源于stack exchange,提问作者user644361
相关产品推荐
相关产品推荐

