c++中STL的迭代器失效问题(力扣编程遇到的)

迭代器失效,有两个层面的意思,
1) 无法通过迭代器++,--操作遍历整个stl容器。
2) 无法通过迭代器存取迭代器所指向的内存,因为数据移动之后原来迭代器指向的地址并不是正确的数据。

 

1.STL中的容器分类

1.1序列式:

vector(动态数组)、list(双向链表)、deque(双端队列)以及基于双端队列的stack(栈)、queue(队)

1.2关联式:

map/set    、multimap/set  (有序关联式:红黑树)

unordered_map/set   、unodered_multimap/set   (无序关联式:哈希表)

根据实际存储的分类可以分为顺序存储和链式存储:其中vector和deque都是顺序存储,其各个元素的地址是前后相连的,这就意味着在执行插入和删除的时候,插入或删除位置之后的迭代器会全部失效(因为数据发生了移动)

而链表和关联式容器(树形),其中的元素地址并不相连,插入和删除只会改变当前位置的地址,即只会造成单个迭代器失效

vector迭代器失效问题总结

(1)当执行erase方法时,指向删除节点的迭代器全部失效,指向删除节点之后的全部迭代器也失效 
(2)当进行push_back()方法时,end操作返回的迭代器肯定失效。 
(3)当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。 
(4)当插入(push_back)一个元素后,如果空间未重新分配,指向插入位置之前的元素的迭代器仍然有效,但指向插入位置之后元素的迭代器全部失效。

deque迭代器失效总结:

(1)对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用都会失效,但是如果在首尾位置添加元素,迭代器会失效,但是指针和引用不会失效 
(2)如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器全部失效 
(3)在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。

总结:迭代器失效分三种情况考虑,也是非三种数据结构考虑,分别为数组型,链表型,树型数据结构。

数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);

链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器

注意:经过 erase(iter) 之后的迭代器完全失效,该迭代器 iter 不能参与任何运算,包括 iter++,*ite 

猜你喜欢

转载自blog.csdn.net/weixin_42067304/article/details/110739570
今日推荐