反向迭代器和正向迭代器相反,比如一个数组内容是1,2,3,4,5。正向迭代器就是按顺序输出,反向迭代器是5,4,3,2,1,顺序倒着。想要第一个输出5,需要反向迭代器rbegin在5的位置,判断输出完的条件,rend在头节点的位置就行,只需要将指针相加重载为取前一个数据,这就需要和正向迭代器一样封装一个反向迭代器的类
先用链表的迭代器做示范
template <class T, class Ref, class Ptr>
struct __list_reverse_iterator
{
typedef __list_node<T> node;
typedef __list_reverse_iterator<T, Ref, Ptr> self;
__list_reverse_iterator(node* it_node)
{
node_iterator = it_node;
}
Ref operator*()
{
return node_iterator->_data;
}
Ptr operator->()
{
//return &node_iterator->_data;
return &(operator*());
}
self& operator++()
{
node_iterator = node_iterator->_prev;
return *this;;
}
self operator++(int)
{
self tmp(*this);
node_iterator = node_iterator->_prev;
return tmp;;
}
self& operator--()
{
node_iterator = node_iterator->_next;
return *this;;
}
self operator--(int)
{
self tmp(*this);
node_iterator = node_iterator->_next;
return tmp;;
}
bool operator!=(const self& x)
{
return node_iterator != x.node_iterator;
}
bool operator==(const self& x)
{
return node_iterator == x.node_iterator;
}
node* node_iterator;
};
reverse_iterator rbegin()
{
reverse_iterator tmp(_head._prev);
return tmp;
}
reverse_iterator rend()
{
reverse_iterator tmp(_head);
return tmp;
}
和正向迭代器唯一不一样的地方就是++返回的是节点前一个位置,–返回后一个位置
rbegin返回最后一个数据的位置,rend一样返回头节点
看看标准库中怎么实现的
库里用了迭代器萃取,意思是总结出了反向迭代器的特性,以至于这个类的迭代器可以适用于其他数据结构。对于链表我们可以重载它的++,因为将指针封装成了类,而vector的迭代器就是原生指针的重命名,当然,也可以封装为类就可以实现反向迭代器,不过过于麻烦。用这样一个反向迭代器的类,可以实现其他所有数据的反向迭代器,只需要传入对应数据类型的正向迭代器就能构造反向迭代器,这是如何实现的
它的取内容实际上是取的正向迭代器–后的内容,这是为什么
反向迭代器的rbegin用正向的rend构造,说明刚好两个迭代器的位置是相反的
这样反向迭代器取当前内容就需要取前一个节点的值,rbegin在2的位置是,输出的是值1。这样迭代器的构造也只需要传入正向迭代器的begin就行,对称了
迭代器萃取比较麻烦,我们先用加两个模板参数的方法实现,和正向迭代器类似,不同的是不需要传入数据类型,需要传入正向迭代器
template <class Iterator, class Ref, class Ptr>
struct __list_reverse_iterator
{
typedef __list_reverse_iterator<Iterator, Ref, Ptr> self;
__list_reverse_iterator(Iterator it)
:_cur(it)
{}
Ref operator*()
{
Iterator tmp = _cur;
tmp--;
return *tmp;
}
Ptr operator->()
{
return &(operator*());
}
self& operator++()
{
_cur--;
return *this;
}
self operator++(int)
{
self tmp(*this);
_cur--;
return tmp;;
}
self& operator--()
{
_cur++;
return *this;;
}
self operator--(int)
{
self tmp(_cur.node_iterator._next);
_cur++;
return tmp;
}
bool operator!=(const self& x)
{
return _cur != x._cur;
}
bool operator==(const self& x)
{
return _cur == x._cur;
}
Iterator _cur;
};
typedef __list_reverse_iterator<iterator, T&, T*> reverse_iterator;
reverse_iterator rbegin()
{
reverse_iterator tmp(end());
return tmp;
}
reverse_iterator rend()
{
reverse_iterator tmp(begin());
return tmp;
}
这里*取正向迭代器–后的内容,会自动调用正向迭代器的重载函数。++就–,和正向相反,比较的时候本质是指针的比较
将这个类放到vector同样也可以使用,代码不需要改变,这样就做到了多用
list全代码
#pragma once
#include <assert.h>
namespace mylist
{
template <typename T>
struct __list_node
{
__list_node(const T& x = T())
: _prev(nullptr)
, _next(nullptr)
, _data(x)
{}
__list_node<T>* _prev;
__list_node<T>* _next;
T _data;
};
//迭代器
template <class T, class Ref, class Ptr>
struct __list_iterator
{
typedef __list_node<T> node;
typedef __list_iterator<T, Ref, Ptr> self;
__list_iterator(node* it_node)
{
node_iterator = it_node;
}
Ref operator*()
{
return node_iterator->_data;
}
Ptr operator->()
{
//return &node_iterator->_data;
return &(operator*());
}
self& operator++()
{
node_iterator = node_iterator->_next;
return *this;;
}
self operator++(int)
{
self tmp(*this);
node_iterator = node_iterator->_next;
return tmp;;
}
self& operator--()
{
node_iterator = node_iterator->_prev;
return *this;;
}
self operator--(int)
{
self tmp(*this);
node_iterator = node_iterator->_prev;
return tmp;;
}
bool operator!=(const self& x)
{
return node_iterator != x.node_iterator;
}
bool operator==(const self& x)
{
return node_iterator == x.node_iterator;
}
node* node_iterator;
};
//反向迭代器
//template <class T, class Ref, class Ptr>
//struct __list_reverse_iterator
//{
// typedef __list_node<T> node;
// typedef __list_reverse_iterator<T, Ref, Ptr> self;
// __list_reverse_iterator(node* it_node)
// {
// node_iterator = it_node;
// }
// Ref operator*()
// {
// return node_iterator->_data;
// }
// Ptr operator->()
// {
// //return &node_iterator->_data;
// return &(operator*());
// }
// self& operator++()
// {
// node_iterator = node_iterator->_prev;
// return *this;;
// }
// self operator++(int)
// {
// self tmp(*this);
// node_iterator = node_iterator->_prev;
// return tmp;;
// }
// self& operator--()
// {
// node_iterator = node_iterator->_next;
// return *this;;
// }
// self operator--(int)
// {
// self tmp(*this);
// node_iterator = node_iterator->_next;
// return tmp;;
// }
// bool operator!=(const self& x)
// {
// return node_iterator != x.node_iterator;
// }
// bool operator==(const self& x)
// {
// return node_iterator == x.node_iterator;
// }
// node* node_iterator;
//};
//反向迭代器库写法
template <class Iterator, class Ref, class Ptr>
struct __list_reverse_iterator
{
typedef __list_reverse_iterator<Iterator, Ref, Ptr> self;
__list_reverse_iterator(Iterator it)
:_cur(it)
{}
Ref operator*()
{
Iterator tmp = _cur;
tmp--;
return *tmp;
}
Ptr operator->()
{
return &(operator*());
}
self& operator++()
{
_cur--;
return *this;
}
self operator++(int)
{
self tmp(*this);
_cur--;
return tmp;;
}
self& operator--()
{
_cur++;
return *this;
}
self operator--(int)
{
self tmp(_cur.node_iterator._next);
_cur++;
return tmp;;
}
bool operator!=(const self& x)
{
return _cur != x._cur;
}
bool operator==(const self& x)
{
return _cur == x._cur;
}
Iterator _cur;
};
template <class T>
class list
{
typedef __list_node<T> node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef __list_reverse_iterator<iterator, T&, T*> reverse_iterator;
iterator begin()
{
iterator tmp(_head->_next);
return tmp;
}
iterator end()
{
iterator tmp(_head);
return tmp;
}
const_iterator begin() const
{
const_iterator tmp(_head->_next);
return tmp;
}
const_iterator end() const
{
const_iterator tmp(_head);
return tmp;
}
reverse_iterator rbegin()
{
reverse_iterator tmp(end());
return tmp;
}
reverse_iterator rend()
{
reverse_iterator tmp(begin());
return tmp;
}
//构造
void empyt_init()
{
_head = new node;
_head->_prev = _head->_next = _head;
}
list()
{
empyt_init();
}
template <class InputIterator>
list(InputIterator first, InputIterator last)
{
empyt_init();
while (first != last)
{
push_back(*first);
first++;
}
}
void swap(list<T>& x)
{
std::swap(_head, x._head);
}
list(const list<T>& x)
{
empyt_init();
list<T> tmp(x.begin(), x.end());
swap(tmp);
/*const_iterator it = x.begin();
while (it != x.end())
{
push_back(*it);
it++;
}*/
/*for (auto e : x)
{
push_back(e);
}*/
}
list<T>& operator=(list<T> x)
{
swap(x);
return *this;
}
//add
void push_front(const T& x)
{
Insert(begin(), x);
}
void push_back(const T& x)
{
node* new_node = new node(x);
_head->_prev->_next = new_node;
new_node->_prev = _head->_prev;
_head->_prev = new_node;
new_node->_next = _head;
}
void Insert(iterator pos, const T& x)
{
node* new_node = new node(x);
//记录前后节点
node* pre = pos.node_iterator->_prev;
node* cur = pos.node_iterator;
//连接
pre->_next = new_node;
new_node->_prev = pre;
new_node->_next = cur;
cur->_prev = new_node;
}
//de
void pop_front()
{
Erase(begin());
}
void pop_back()
{
Erase(--end());
}
iterator Erase(iterator pos)
{
//头节点不能删
assert(pos != end());
node* prev = pos.node_iterator->_prev;
node* next = pos.node_iterator->_next;
prev->_next = next;
next->_prev = prev;
delete pos.node_iterator;
return iterator(next);
}
//析构
void clear()
{
iterator it = begin();
while (it != end())
{
Erase(it++);
}
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
private:
node* _head;
};
}