关于迭代器失效

2 篇文章 0 订阅

(前置技能)关于++i和i++

i++的过程:先拷贝一份原始值至另外的内存地址中,然后这份被拷贝的原始值应用于后续的计算过程中,然后自身加1;
++i的过程:先自增,然后把自增后的值拷贝一份到另外的内存地址中,这份被拷贝的值应用于后续计算。

内建数据类型的情况,效率没有区别。
自定义数据类型的情况,++i效率较高。

erase方法可以返回下一个有效的iterator

set,map的迭代器失效

typedef map<int, int> Map;
typedef map<int, int>::iterator MapIt;

Map m;
MapIt it;
for(it = m.begin(); it != m.end(); /*不能再自增了,不能i++*/){ //因为对于关联的容器map来说, m.erase(it);后,it就失效了
	if(*it%2 == 0)
		m.erase(it++);//这个原理看上面i++
	else
		it++;


	//正解
	if(*it%2 == 0)
		it = m.erase(it);//通过erase方法的返回值来获取下一个有效迭代器
	else
		it++;
}


vector,deque的迭代器失效

//序列式容器,使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。

vector<int> v;
for(vector<int>::iterator it = v.begin(); it != v.end(); /*不能再自增了*/){
	it = v.erase(it); // 删除当前的iterator,后面的vector元素自动向前挪动,后面的迭代器全部会失效(关联的map容器元素不会自动挪动), 所以不能再把it进行++
}

触发各容器迭代器失效的情况

list

内部数据结构:双向环状链表。
使用了不连续分配的内存,它的erase方法也会返回下一个有效的iterator,因此上面两种迭代方法都可以使用。

增加任何元素都不会使迭代器失效。删除元素时,除了指向当前被删除元素的迭代器外,其它迭代器都不会失效。

vector

内部数据结构:数组。

vector的迭代器在内存重新分配时将失效 或
指向当前元素以后的任何元素的迭代器都将失效。
(重新分配内存并添加元素 和 删除或者添加但不重新分配 分别对应这两种情况)

当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。
(因为数据结构是数组,明显知道删除后会使后面所有元素改变,所以删除O(n)也可以证明)

stack, queue

一般使用deque作为支持的序列容器。
不能遍历。。

map, set

关联式容器:使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。
如果迭代器所指向的元素被删除,则该迭代器失效。

deque

增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值