模拟实现list和vector反向迭代器
创始人
2024-05-09 01:16:18
0

学习这部分知识,需要你了解vector和list的正向迭代器知识以及容器适配器知识,可以阅读我写的另外三篇vector、list、容器适配器 知识的博客!其中list知识内容尤其重要且难度要求很高!

反向迭代器,顾名思义是与正向迭代器相对,作用是反向遍历容器数据!

目录

一、反向迭代器

1.1 反向迭代器相关函数

1.1.1 rbegin() 

 1.1.2 rend() 

1.2反向迭代器反向遍历vector和list

1.2.1 反向遍历vector

1.2.2 反向遍历list

 二、模拟实现vector反向迭代器

2.1 vector正向迭代器

2.2 vector反向迭代器

2.3 模拟测试遍历vector

2.3.1 const反向迭代器效果

2.3.2  反向迭代器遍历

三、模拟实现list反向迭代器

3.1 list 正向迭代器

3.2 模拟实现list反向迭代器

3.3 测试反向迭代器遍历 

3.3.1 const迭代器效果展示

3.3.2 反向迭代器遍历list

 四、模拟实现vector完整版

五、模拟实现list完整版


一、反向迭代器

1.1 反向迭代器相关函数

C++11中加了独立的返回const迭代器的函数,但这篇博客只模拟实现list的const函数重载来返回const迭代器! 具体这些函数请查看cplusplus.com - The C++ Resources Network

1.1.1 rbegin() 

返回值:返回指向容器中最后一个元素(即其反向开头)的反向迭代器!

const修饰的函数返回值:返回const反向迭代器,其指向成员不能被修改!

 1.1.2 rend() 

返回值:返回一个反向迭代器,该迭代器指向容器中第一个元素之前的理论元素

const修饰的函数返回值:返回const反向迭代器,其指向成员不能被修改!

1.2反向迭代器反向遍历vector和list

1.2.1 反向遍历vector

1.2.2 反向遍历list


 二、模拟实现vector反向迭代器

2.1 vector正向迭代器

namespace wyz//与标准库vector区别,自己定义一个命名空间,在里面写!
{templateclass vector{public://...//迭代器typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator cbegin()const{return _start;}const_iterator cend()const{return _finish;}private:iterator _start;iterator _finish;iterator _end_of_storage;};

2.2 vector反向迭代器

反向迭代器是反向遍历容器数据,它也要满足++、--、*、==、!=的功能,只不过它的++是从后往前,--是从前往后。我们很容易可以想到,反向迭代器和正向的功能差不多相同,只不过在++,--的效果相反!vector正向迭代器底层是指针,它的算法迎合基本的逻辑,++向后,--向前!我们无法直接实现让变量++指针减小,--指针增加!所以我们要用到容器适配器,底层我们可以用正向迭代器!反向的效果只要让正向反着来!--让正向++,++让正向--!这样一来我们的遍历就可以实现!也就是说,我们要将反向迭代器封装成类

下面我们直接上代码:

templatestruct vector_reverse_iterator{typedef vector_reverse_iterator Self;public://拷贝构造vector_reverse_iterator(iterator s){_it = _it;}Self& operator++(){--_it;return *this;}Self& operator--(){++_it;return *this;}T operator*(){iterator tmp = _it;return *(--tmp);//注意这个返回!}bool operator!=(Self s){return _it != s._it;}bool operator==(Self s){return _it == s._it;}private:iterator _it;};

 在来看看vector中的反向迭代器的申明与相关函数:

typedef T* iterator;
typedef const T* const_iterator;
typedef vector_reverse_iterator  reverse_iterator;
typedef vector_reverse_iterator const_reverse_iterator;
//正向迭代器
iterator begin()
{return _start;
}
iterator end()
{return _finish;
}
const_iterator cbegin()const
{return _start;
}
const_iterator cend()const
{return _finish;
}
//反向迭代器传参,这里为了与正向对称,直接传_finish和_start
reverse_iterator rbegin()
{return reverse_iterator(_finish);
}
reverse_iterator rend()
{return reverse_iterator(_start);
}
//const反向迭代器,不能修改迭代器指向数据!
const_reverse_iterator crbegin()const
{return const_reverse_iterator(_finish);
}
const_reverse_iterator crend()const
{return const_reverse_iterator(_start);
}

💡💡现在这里主要的一个细节问题就是反向迭代器*解引用返回值!为什么要用临时变量先--后解引用返回?画一张图带你来看看!

 这里因为我的rbegin()传参为了与正向对称,没有修改迭代器初始指向!如果我让rbegin()返回的是, return reverse_iterator(_finish-1); 同样rend()返回 reverse_iterator(_start-1),就不用像上面那样先--再*了!直接*返回就可以!

2.3 模拟测试遍历vector

2.3.1 const反向迭代器效果

满足const修饰不能修改数据!


2.3.2  反向迭代器遍历

void vector_test_4()
{wyz::vectorv;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);wyz::vector::reverse_iterator rit = v.rbegin();while (rit != v.rend()){cout << *rit << ' ';++rit;}cout << endl;
}
void vector_test_5()
{wyz::vectorv;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);wyz::vector::const_reverse_iterator crit = v.crbegin();while (crit != v.crend()){cout << *crit << ' ';++crit;}cout << endl;
}
int main()
{cout << "vector_test_4()测试结果:";vector_test_4();cout << "vector_test_5()测试结果:";vector_test_5();return 0;
}

 


三、模拟实现list反向迭代器

3.1 list 正向迭代器

template
struct list_iterator
{typedef list_node node;typedef list_iterator Self;node* pnode;list_iterator(node* p):pnode(p){}ref operator*(){return pnode->data;}ptr operator->(){return &pnode->data;}//前置Self& operator++(){pnode = pnode->next;return *this;}//后置Self operator++(int){Self tmp(pnode);pnode = pnode->next;return tmp;}//前置Self& operator--(){pnode = pnode->prev;return *this;}//后置Self operator--(int){Self tmp(pnode);pnode = pnode->prev;return tmp;}bool operator!=(const Self& it){return pnode != it.pnode;}bool operator==(const Self& it){return pnode == it.pnode;}
};

3.2 模拟实现list反向迭代器

经过前面的vecotr反向迭代器模拟,我们知道其实反向迭代器可以用正向作容器,实现容器适配器!下面我们来实现list反向迭代器。

下面我们上代码:

template
class list_reverse_iterator
{typedef list_reverse_iterator self;
public:list_reverse_iterator(iterator it):_it(it){}self& operator++(){--_it;return *this;}self& operator--(){++_it;return *this;}ref operator*(){iterator tmp = _it;return *(--tmp);//注意这里的先--后*}ptr operator->(){return &(operator*());//ref=T& &ref=&(T&) 即相当于T*=ptr}bool operator!=(const self& s){return _it != s._it;}bool operator==(const self& s){return _it == s._it;}
private:iterator _it;
};

我们再来看看list的反向迭代器申明与相关函数:

typedef list_iterator iterator;
typedef list_iterator const_iterator;
typedef list_reverse_iterator reverse_iterator;
typedef list_reverse_iterator const_reverse_iterator;iterator begin()
{//匿名对象返回!return iterator(head->next);
}
iterator end()
{return iterator(head);
}
const_iterator begin()const
{return const_iterator(head->next);
}
const_iterator end()const
{return const_iterator(head);
}//反向迭代器
reverse_iterator rbegin()
{return reverse_iterator(end());
}
reverse_iterator rend()
{return reverse_iterator(begin());
}
//const函数重载返回const反向迭代器
const_reverse_iterator rbegin()const
{return const_reverse_iterator(end());
}
const_reverse_iterator rend()const
{return const_reverse_iterator(begin());
}

思路几乎和上面的vector一样,这里我们还要再说明一下为什么这里还是先--后*! 我们可以看到反向迭代器相关函数依然与正向相对称!我们还是画图来理解!


3.3 测试反向迭代器遍历 

3.3.1 const迭代器效果展示

3.3.2 反向迭代器遍历list

void list_test_4()
{const wyz::list clt;clt.push_back(1);clt.push_back(2);clt.push_back(3);clt.push_back(4);clt.push_back(5);wyz::list::const_reverse_iterator const_rit = clt.rbegin();while (const_rit != clt.rend()){//cout << (*const_rit)++ << ' ';cout << *const_rit << ' ';++const_rit;}cout << endl;
}
void list_test_5()
{wyz::list lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);wyz::list::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << ' ';++rit;}cout << endl;
}
int main()
{cout << "list_test_4()测试结果:";list_test_4();cout << "list_test_5()测试结果:";list_test_5();return 0;
}


 四、模拟实现vector完整版

namespcae wyz
{
template
class vector
{
public://构造函数vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}vector(const vector& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(v.size());for (auto& e : v){push_back(e);}}void swap(vector& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}vector& operator=(vector tmp){swap(tmp);return *this;}//这里为了更加直观化,不用T* 而是重新定义一个模板Inputiteratortemplatevector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(last - first);while (first != last){push_back(*first);first++;}}vector(int n, const T& val = T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(n);while (n){push_back(val);n--;}}//析构函数~vector(){delete[]_start;_start = nullptr;_finish = nullptr;_end_of_storage = nullptr;}//返回空间数据个数size_t size()const{return _finish - _start;}//返回空间大小size_t capacity()const{return _end_of_storage - _start;}//预开辟空间void reserve(size_t n){if (n > capacity()){//记录数组有效个数size_t sz = size();T* tmp = new T[n];if (_start){for (int i = 0;i < sz;i++){tmp[i] = _start[i];}delete[]_start;}//更新_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}//预指定数据个数void resize(size_t n, T val = T()){if (n > capacity()){//预开辟空间reserve(n);//尾插while (_finish < _start + n){*_finish = val;_finish++;}}//nstruct vector_reverse_iterator{typedef vector_reverse_iterator Self;public:vector_reverse_iterator(iterator it){_it = it;}Self& operator++(){--_it;return *this;}Self& operator--(){++_it;return *this;}T operator*(){iterator tmp = _it;return *(--tmp);}bool operator!=(Self s){return _it != s._it;}bool operator==(Self s){return _it == s._it;}private:iterator _it;};//迭代器typedef T* iterator;typedef const T* const_iterator;typedef vector_reverse_iterator  reverse_iterator;typedef vector_reverse_iterator const_reverse_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator cbegin()const{return _start;}const_iterator cend()const{return _finish;}reverse_iterator rbegin(){return reverse_iterator(_finish);}reverse_iterator rend(){return reverse_iterator(_start);}const_reverse_iterator crbegin()const{return const_reverse_iterator(_finish);}const_reverse_iterator crend()const{return const_reverse_iterator(_start);}//返回数组指定位置内容T& operator[](size_t pos){return _start[pos];}const T& operator[](size_t pos)const{return _start[pos];}bool empty(){return _start == _finish;}void clear(){_start = _finish;}//尾插void push_back(const T& x){//判断是否需要扩容if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}*(_finish) = x;_finish++;}//尾删void pop_back(){assert(!empty());_finish--;}//指定位置插入void insert(iterator pos, T x){size_t n = pos - _start;//判断是否需要扩容if (_finish == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);pos = _start + n;}iterator end = _finish;while (end >= pos){*(end + 1) = *end;end--;}*(end + 1) = x;_finish++;}//指定位置删除iterator erase(iterator pos){assert(!empty());iterator begin = pos;while (begin != _finish - 1){*begin = *(begin + 1);begin++;}_finish--;return pos;}
private:iterator _start;iterator _finish;iterator _end_of_storage;
};
}

五、模拟实现list完整版

namespace wyz
{templatestruct list_node{list_node(const T& val=T()):prev(nullptr),next(nullptr),data(val){}public:list_node* prev;list_node* next;T data;};templatestruct list_iterator{typedef list_node node;typedef list_iterator Self;node* pnode;list_iterator(node* p):pnode(p){}ref operator*(){return pnode->data;}ptr operator->(){return &pnode->data;}//前置Self& operator++(){pnode = pnode->next;return *this;}//后置Self operator++(int){Self tmp(pnode);pnode = pnode->next;return tmp;}//前置Self& operator--(){pnode = pnode->prev;return *this;}//后置Self operator--(int){Self tmp(pnode);pnode = pnode->prev;return tmp;}bool operator!=(const Self& it){return pnode != it.pnode;}bool operator==(const Self& it){return pnode == it.pnode;}};templateclass list_reverse_iterator{typedef list_reverse_iterator self;public:list_reverse_iterator(iterator it):_it(it){}self& operator++(){--_it;return *this;}self& operator--(){++_it;return *this;}ref operator*(){iterator tmp = _it;return *(--tmp);}ptr operator->(){return &(operator*());}bool operator!=(const self& s){return _it != s._it;}bool operator==(const self& s){return _it == s._it;}private:iterator _it;};templateclass list{public:typedef list_node node;typedef list_iterator iterator;typedef list_iterator const_iterator;typedef list_reverse_iterator reverse_iterator;typedef list_reverse_iterator const_reverse_iterator;iterator begin(){//匿名对象返回!return iterator(head->next);}const_iterator begin()const{return const_iterator(head->next);}const_iterator end()const{return const_iterator(head);}iterator end(){return iterator(head);}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin()const{return const_reverse_iterator(end());}const_reverse_iterator rend()const{return const_reverse_iterator(begin());}void clear(){iterator first = begin();while (first != end()){first=erase(first);//!!!}}~list(){clear();delete head;head = nullptr;}void empty_initialize(){head = new node;head->next = head;head->prev = head;}list(){empty_initialize();}template list(InputIterator first, InputIterator end){empty_initialize();while (first != end){push_back(*first);++first;}}void swap(list& lt){std::swap(head, lt.head);}list(const list& lt){empty_initialize();list tmp(lt.begin(), lt.end());swap(tmp);}list& operator=(list tmp){swap(tmp);return *this;}void push_back(const T& x)const{insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_front(){erase(begin());}void pop_back(){erase(--end());}void insert(iterator pos,const T& x){node* newnode = new node(x);node* cur = pos.pnode;node* prev = cur->prev;prev->next = newnode;newnode->prev = prev;cur->prev = newnode;newnode->next = cur;}void insert(const_iterator pos, const T& x)const{node* newnode = new node(x);node* cur = pos.pnode;node* prev = cur->prev;prev->next = newnode;newnode->prev = prev;cur->prev = newnode;newnode->next = cur;}iterator erase(iterator pos){node* cur = pos.pnode;node* prev = cur->prev;node* next = cur->next;prev->next = next;next->prev = prev;delete cur;return iterator(next);}const_iterator erase(const_iterator pos)const{node* cur = pos.pnode;node* prev = cur->prev;node* next = cur->next;prev->next = next;next->prev = prev;delete cur;return iterator(next);}private:node* head;//底层是一个哨兵结点};
}

相关内容

热门资讯

美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...
安卓系统7.dns,优化网络连... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,让我来给你揭秘这可能与你的安卓系...
安卓手机系统怎么加速,安卓手机... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机瞬...
小米note安卓7系统,探索性... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,小米Note这款手机,自从升级到了安卓7...
安卓和鸿蒙系统游戏,两大系统游... 你有没有发现,最近手机游戏界可是热闹非凡呢!安卓和鸿蒙系统两大巨头在游戏领域展开了一场激烈的较量。今...
安卓手机没有系统更,揭秘潜在风... 你有没有发现,现在安卓手机的品牌和型号真是五花八门,让人挑花了眼。不过,你知道吗?尽管市面上安卓手机...
充值宝带安卓系统,安卓系统下的... 你有没有发现,最近手机上的一款充值宝APP,在安卓系统上可是火得一塌糊涂呢!这不,今天就来给你好好扒...
安卓系统8.0镜像下载,轻松打... 你有没有想过,想要给你的安卓手机升级到最新的系统,却不知道从哪里下载那个神秘的安卓系统8.0镜像呢?...
安卓系统修改大全,全方位修改大... 你有没有想过,你的安卓手机其实是个大宝藏,里面藏着无数可以让你手机焕然一新的秘密?没错,今天就要来个...