和其他容器一样,在学会创建容器后我们就要认识其迭代器。list同我们学过的vector一样,也有begin()、end()正向迭代器,rbegin()、rend()反向迭代器,更有可读不可改的cbegin()、cend()、crbegin()、crend()这种常量迭代器(c这里表示const,意为不可修改)。他们在链表中的位置如下图所示:
list和之前学过的deque、vector、array一样都是双向迭代器,支持++和--操作,但不是随机迭代器,不支持+5、-2操作。在前一节《初识STL库中的list容器》,我们通过begin()实现了list容器遍历,现在我们使用rbegin()来实现容器遍历:
#include<bits/stdc++.h> #include<list> /*通过list反向迭代器遍历容器 */ using namespace std; void test() { list<int> l;//直接创建 for(int i=0;i<5;++i) { l.push_front(i+1);//链表也能通过push_front()头增元素 } /*{5,4,3,2,1}*/ for(auto it = l.rbegin();it!=l.rend();++it)cout << *it << " ";//链表不能通过'[]'访问元素 cout << '\n'; } int main(){ test(); return 0; }
编译后:
成功编译。值得注意的是正向迭代器是左减右加,反向迭代器是左加右减,在使用迭代器时要注意方向不要错了。
前面我们谈到,在使用vector、deque时,当容器进行”扩展行为“后需要更新迭代器,这是因为地址发生了变化。而我们的list容器则无需更新,这是由于list的结构就是通过指针链接新地址,原来数据没有更改地址,所以无需更新迭代器。举个例子:
vector进行“扩展行为”或“收缩行为”都需要及时更新迭代器:
#include<bits/stdc++.h> #include<list> #include<vector> /*vector进行“扩展行为”或“收缩行为”都需要及时更新迭代器 */ using namespace std; void test() { vector<int> v{1,2,3,4,5}; vector<int>::iterator beg = v.begin(); cout << "能够输出第一个元素为:"<< *beg<<'\n' ; cout << "容器扩展后未能及时更新迭代器\n" ; v.push_back(6); cout <<"输出第一个元素为: "<< *beg<<'\n'; } int main(){ test(); return 0; }
编译结果为:
可以看到由于没有及时更新迭代器导致第一个迭代器解引用的值是11475440,这完全与1不相同,所以在使用vector等容器进行“扩展行为”或“收缩行为”都需要及时更新迭代器!
相比于list,则无需考虑这个,让我们通过代码来验证:
#include<bits/stdc++.h> #include<list> #include<vector> /*list进行“扩展行为”或“收缩行为”无需更新迭代器 */ using namespace std; void test() { list<int> l{1,2,3,4,5}; list<int>::iterator beg = l.begin(); cout << "能够输出第一个元素为:"<< *beg<<'\n' ; cout << "容器扩展后未能及时更新迭代器\n" ; l.push_back(6); cout <<"输出第一个元素为: "<< *beg<<'\n'; list<int>::iterator end = --l.end(); cout << "能够输出最后一个元素为:"<< *end<<'\n' ; cout << "容器扩展后未能及时更新迭代器\n" ; l.pop_front(); cout <<"输出最后一个元素为: "<< *end<<'\n'; } int main(){ test(); return 0; }
通过对比试验,我的深刻认识到list可以不用像vector那样动态更新迭代器。
总结:本节我们详细了解了list迭代器的使用方法:list迭代器非随机迭代器,不能通过+5、-8这样随机访问(原因在于非连续内存存储),同时由于list特殊结构(由指针链接,无需更换地址),使得list进行“扩展行为”或“收缩行为”无需更新迭代器!
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程