关于C++迭代器的一些讨论(迭代器互相转化,效率,erase操作的影响 )。

关于c++迭代器的一些讨论。

具体结论已经经过实验。

c++STL库封装了一些非常常用的数据结构,但是想要熟悉掌握这些就不能不熟悉迭代器。

主要说三个问题以及结论

  • 正向迭代器与反向迭代器的相互转化以及转化的效率问题: 转化是O(1)还是O(log)的不太清楚。
  • .删除迭代器指向的元素后,it++ 还有效吗?
  • 删除迭代器指向的元素后,it会自动移动到下一个位置吗?
  • 正向迭代器和反向迭代器同样能够 − − ​ --​ 吗?

1 . 正向迭代器与反向迭代器的相互转化以及转化的效率问题

这里以 s e t < i n t > set<int> set<int> 容器为例子, i t it it表示其正向迭代器, r i t rit rit表示其反向迭代器。

1.正向迭代器转化为反向迭代器

    rit=reverse_iterator<set<int>::iterator >(it);

2.反向迭代器转化为正向迭代器

	it=rit.base();

效率不太确定,反正不是O(n)的。应该是O(1) 或者O(logn)


但是需要注意的是,转化后 i t it it r i t rit rit 的指向的位置不是同一个, r i t rit rit i t it it的前面位置

1.正向迭代器转化为反向迭代器

所以我们为了使得转化后rit和it指向同一个位置,我们都这样做。

#include
using namespace std;
set<int> mmp;
int main(){
    mmp.insert(1);
    mmp.insert(2);
    mmp.insert(3);
    set<int>::iterator it=mmp.find(2);
    set<int>::reverse_iterator rit;
    rit=reverse_iterator<set<int>::iterator>(it);
    rit--;
    cout<<*rit<<endl;//输出2
}

2.反向迭代器转化为正向迭代器

#include
using namespace std;
set<int> mmp;
int main(){
    mmp.insert(1);
    mmp.insert(2);
    mmp.insert(3);
    set<int>::iterator it=mmp.begin();
    set<int>::reverse_iterator rit=mmp.rbegin();
    it=rit.base();
    it--;
//    cout<<*it<
}

2. 删除迭代器指向的元素后,it++ 还有效吗?

​ 这里分两种类型容器讨论

  • 关联容器(map、set等)

​ 答:没有效果,只要是这个迭代器指向的位置被删除了,那么对这个迭代器进行任何操作都可能出错。


​ 比如:

#include
using namespace std;
set<int> mmp;
int main(){
    mmp.insert(1);
    mmp.insert(2);
    mmp.insert(3);
    set<int>::iterator it=mmp.begin();
    mmp.erase(it);
    it++;
    /*一个错误的演示,可能会出错*/
}

一般可以这样写,传进去一个复制的 i t it it,(这个操作的本质跟问题描述的不一样,问题描述是先删除,后++;而这里是先++,删除前一个;达到的是同样的效果)。

#include
using namespace std;
set<int> mmp;
int main(){
    mmp.insert(1);
    mmp.insert(2);
    mmp.insert(3);
    set<int>::iterator it=mmp.begin();
    mmp.erase(it++);/*it不会失效*/
}

这样因为删除该元素之前,迭代器的位置已经指向下一个元素,故不会失效。

  • 顺序容器(list、vector、deque等)

    答:没有效果,且之前的所有迭代器变量可能都会失效

    原理的话我想大概就是这样的。比如一个vector容器,你删除一个元素后可能这个数组会全部拷贝到另一个地方,这样的话原来的指针就都无效了。


​ 但是其erase成员函数会返回下一个元素的迭代器。

#include
using namespace std;
list<int> a;
int main(){
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    list<int>::iterator it=a.begin();
    cout<<*it<<endl;//1
    it=a.erase(it);
    cout<<*it<<endl;//2
}

3.删除迭代器指向的元素后,it会自动移动到下一个位置吗?

​ 答:不会


​ 这是我见过最**的问题,而且我曾经对这个问题有一丝的相信(笑哭~)。我记得有一次面试题就这个问题。

4.正向迭代器和反向迭代器同样能够 − − -- 吗?

​ 答:是的 正向迭代器和反向迭代器都支持++,–操作

你可能感兴趣的:(c++,迭代器,专项之C/C++)