当前位置:首页 » 《关注互联网》 » 正文

C++:反向迭代器

11 人参与  2024年10月26日 11:20  分类 : 《关注互联网》  评论

点击全文阅读


文章目录

一、什么是反向迭代器?1.1 反向迭代器与正向迭代器的关系1.2 反向迭代器实现原理1.3 反向迭代器代码 二、list中的反向迭代器2.1 定义2.2 使用 三、vector中的反向迭代器3.1 定义3.2 使用 总结


在这里插入图片描述

一、什么是反向迭代器?

反向迭代器的++就是正向迭代器的–,反向迭代器的–就是正向迭代器的++,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。

1.1 反向迭代器与正向迭代器的关系

反向迭代器其实是由正向迭代器适配出来的,它的++,--与正向迭代器相反,它的rbegin是正向迭代器的end,它的rend是正向迭代器的begin,反向迭代器与正向迭代器是镜面对称的。

反向迭代器也是一个模板,传list的迭代器,就是list的反向迭代器,传vector的迭代器就是vector的反向迭代器。

在这里插入图片描述


1.2 反向迭代器实现原理

反向迭代器的++就是正向迭代器的–,反向迭代器的–就是正向迭代器的++,它的rbegin是正向迭代器的end,它的rend是正向迭代器的begin,因此它的解引用需要返回当前迭代器--的迭代器解引用。

在这里插入图片描述

在这里插入图片描述


1.3 反向迭代器代码

这里为了能有返回值,也要传Ref和Ptr

namespace bit{template<class T, class Ref, class Ptr>struct ReverseIterator{typedef ReverseIterator<T, Ref, Ptr> Self;Iterator _it;ReverseIterator(Iterator it):_it(it){}Ref operator* (){Iterator tmp = _it;return *(--tmp);}Ptr operator-> (){return &(operator*());}Self& operator++ (){--_it;return *this;}Self& operator-- (){++_it;return *this;}bool operator!= (const Self& s) const{return _it != s._it;}};}

二、list中的反向迭代器

2.1 定义

首先要typedef出来反向迭代器,像这样:

typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;typedef ReverseIterator<T, T&, T*> reverse_iterator;typedef ReverseIterator<T, const T&, const T*> const_reverse_iterator;

接着还要提供对应rbegin与rend的获取:

iterator begin(){//return _head->_next;return iterator(_head->_next);}iterator end(){return _head;//return iterator(_head);}const_iterator begin() const{//return _head->_next;return const_iterator(_head->_next);}const_iterator end() const{return _head;//return const_iterator(_head);}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin() const{return reverse_iterator(end());}const_reverse_iterator rend() const{return reverse_iterator(begin());}

2.2 使用

反向迭代器就像这样使用:

void test_list(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;}}

三、vector中的反向迭代器

3.1 定义

typedef T* iterator;typedef const T* const_iterator;//这里都是一模一样的,不过传的迭代器不一样罢了,这就是模板的魅力!//编译器会帮我们完成工作!!!typedef ReverseIterator<iterator, T&, T*> reverse_iterator;typedef ReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;

接着还要提供对应rbegin与rend的获取:

reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}

3.2 使用

它的使用从表面上看和list的一模一样

void test_vector1(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);for (auto e : v1){cout << e << " ";}cout << endl;vector<int>::reverse_iterator rit = v1.rbegin();while (rit != v1.rend()){cout << *rit << " ";++rit;}cout << endl;}}

总结

listvector 的反向迭代器表面上看起来使用相同,但它们背后的实现其实有较大的差异。以下是对 listvector 反向迭代器的区别总结:

容器结构的不同

vectorvector 是连续存储的动态数组,所有元素在内存中是连续排列的,反向迭代器在 vector 中只需调整指针的偏移量。listlist 是一个双向链表,元素分散在不同的内存位置,反向迭代器必须沿着链表的指针进行跳转,而不是简单的指针加减操作。

访问方式的不同

vector 反向迭代器vector 允许随机访问,因此反向迭代器可以通过简单的指针运算快速定位任意元素,比如通过 rit + n 访问偏移 n 的元素。list 反向迭代器list 不支持随机访问,因此不能通过 +- 来偏移反向迭代器,只能通过逐个遍历(++--)来前进或后退。

底层机制的不同

vector 反向迭代器:在 vector 中,反向迭代器其实是基于普通迭代器的简单封装,它只是改变了普通迭代器的前进和后退方向。rbegin() 返回的是指向最后一个元素的迭代器,而 rend() 返回的是第一个元素前面的虚拟位置。list 反向迭代器:在 list 中,反向迭代器是通过链表的前驱指针来完成反向遍历。每次前进时,反向迭代器都会通过前驱指针找到前一个元素的位置,因此遍历时比 vector 复杂得多。

因此,虽然表面上看起来一模一样,实际上编译器替我们完成了复写一遍的行为,这就是模板和适配器造就的迭代器!

谢谢大家!!!??????☆*: .。. o(≧▽≦)o .。.:*☆

在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/177902.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1