list,set,map等以节点形式存储的容器
删除元素
删除元素只会导致被删除元素的迭代器失效,其他迭代器仍然有效,erase会返回下一个有效的迭代器
正确写法1:
list<int>li{1,2,3,4};
for (auto it = li.begin(); it != li.end();)
{
if (*it == 2)
{
it = li.erase(it);
}
else
{
it++;
}
}
正确写法2:
for (auto it = li.begin(); it != li.end();)
{
if (*it == 2)
{
li.erase(it++);
}
else
{
it++;
}
}
添加元素
增加元素不会导致迭代器失效
list<int> li{ 1,2,3,4 };
for (auto it = li.begin(); it != li.end();)
{
if (*it == 2)
{
it = li.erase(it);
li.insert(it, 100);
}
else
{
it++;
}
}for (auto temp :li)
{
cout << temp << endl;
}
vector,deque等以数组形式存储的容器
1、删除或插入元素会导致当前迭代器和后面所有元素的迭代器失效
2、当插入的元素超过当前vector的容量时,会重新分配内存空间,会导致所有的迭代器失效
删除元素:
vector<int>v{ 1,2,3,4 };
for (auto it = v.begin(); it != v.end();)
{
if (*it == 2)
{
it = v.erase(it);
}
else
{
it++;
}
}
插入元素
vector<int>v{ 1,2,3,4 };
for (auto it = v.begin(); it != v.end();)
{
if (*it == 2)
{
it = v.insert(it,100);
}
else
{
it++;
}
}
注意:vector、deque 不能像上面的“正确方法2”的办法来遍历删除。原因请参考Effective STL条款9。
- 对于关联容器(如map, set, multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。
因为it传给erase方法的是一个副本,ir++会指向下一个元素。 - 对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。还好erase方法可以返回下一个有效的iterator。