https://blog.csdn.net/qscftqwe/article/details/155534152
这是上节课的链接,大家可以看一下,好了今天我要讲的内容是关于List的正向迭代器和反向迭代器。
一.正向迭代器
cpp
class ListIterator//正向迭代器
{
public:
typedef Node<T> Node;
typedef ListIterator<T, Ref, Ptr>Self;//表示自身
ListIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operator *());
}
Self& operator++()//前置++
{
_node = _node->_next;
return *this;
}
Self operator++(int)//后置++
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
Self& operator--()//前置--
{
_node = _node->_prev;
return *this;
}
Self operator--(int)//后置
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const Self& it)const
{
return _node != it._node;
}
bool operator==(const Self& it)const
{
return _node == it._node;
}
public:
Node* _node;
};
关于List正向迭代器的实现其实并不复杂,关键在于理解为什么要单独封装成类,这与vector的情况有所不同。
迭代器是否需要封装主要取决于其移动方式:当迭代器的++/--操作与指针的++/--行为不一致时,就需要进行封装。
vector之所以不需要封装迭代器,是因为它的元素在内存中是连续存储的,指针的++操作正好对应着向后移动到下一个元素。
而List则不同,它的元素在内存中是分散存储的,需要通过指针跳转到下一个节点位置。这种非连续的移动方式无法通过简单的指针++实现,因此必须进行专门的封装。
二.反向迭代器
cpp
#pragma once
template<typename Iterator, class Ref, class Ptr>
struct reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> Self;
reverse_iterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
Iterator tmp = _it;
return *(--tmp);
}
Ptr operator->()
{
return &(operator*());
}
Self& operator++()
{
--_it;
return *this;
}
Self operator++(int)
{
Self tmp(*this);
--_it;
return tmp;
}
Self& operator--()
{
++_it;
return *this;
}
Self operator--(int)
{
Self tmp(*this);
++_it;
return tmp;
}
bool operator!=(const Self& it)const
{
return _it != it._it;
}
bool operator==(const Self& it)const
{
return _it == it._it;
}
public://该public无作用,主要是标注下面是成员变量
Iterator _it;
};
反向迭代器本质上是对正向迭代器的封装,它在正向迭代器的基础上增加了一层逻辑。具体来说,反向迭代器通过重载运算符实现逆向遍历功能------例如,反向迭代器的++操作实际上调用的是正向迭代器的--操作。
三.获取迭代器的方法
为什么我要讲这个呢,因为List获取迭代器的函数它可能和大家想象的不太一样!
cpp
iterator begin()
{
return _head->_next;
}
iterator end()
{
return _head;
}
就是正向迭代器的begin是第一个节点,end是哨兵位(头节点)!
四.完整代码
cpp
#pragma once
#include<assert.h>
#include"reverse_iterator.h"
#include <cstddef>
#include <utility>
template<class T>
class Node//节点属性
{
public:
Node(const T& data = T())
:_data(data)
,_next(nullptr)
,_prev(nullptr)
{}
public:
T _data;//节点的数据
Node<T>* _next;//下一个节点
Node<T>* _prev;//上一个节点
};
template<class T,class Ref,class Ptr>
class ListIterator//正向迭代器
{
public:
typedef Node<T> Node;
typedef ListIterator<T, Ref, Ptr>Self;//表示自身
ListIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operator *());
}
Self& operator++()//前置++
{
_node = _node->_next;
return *this;
}
Self operator++(int)//后置++
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
Self& operator--()//前置--
{
_node = _node->_prev;
return *this;
}
Self operator--(int)//后置
{
Self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const Self& it)const
{
return _node != it._node;
}
bool operator==(const Self& it)const
{
return _node == it._node;
}
public:
Node* _node;
};
template<class T>
class List
{
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, const T&, const T*> const_iterator;
typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef Node<T> Node;//把类模板声明一下更好写
public:
iterator begin()
{
return _head->_next;
}
iterator end()
{
return _head;
}
const_iterator begin()const
{
return _head->_next;
}
const_iterator end()const
{
return _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());
}
List()//无参构造
:_head(new Node)
,_sz(0)
{
//首尾相连,符合双链表的形态
_head->_next = _head;
_head->_prev = _head;
}
List(const List<T>& lt)
{
//首尾相连,符合双链表的形态
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
for (auto& e : lt)
{
push_back(e);
}
}
~List()
{
clear();//清除
delete _head;
_head = nullptr;
_sz = 0;
}
bool empty()const//判断链表是否为空
{
return _sz == 0;
}
void push_back(const T& data = T())
{
Node* newNode = new Node(data);//创建一个节点
Node* tailNode = _head->_prev;
//构建新节点和尾节点的链接
newNode->_prev = tailNode;
tailNode->_next = newNode;
//构建新节点和头节点的链接
newNode->_next = _head;
_head->_prev = newNode;
_sz++;
}
void pop_back()
{
assert(!empty());//不能为空
Node* tailNode = _head->_prev;//尾节点
Node* tailPrevNode = tailNode->_prev;//尾节点的上一个节点
//构建尾节点的上一个节点和头节点的链接
tailPrevNode->_next = _head;
_head->_prev = tailPrevNode;
delete tailNode;//删除尾节点
_sz--;
}
void push_front(const T& data = T())
{
Node* newNode = new Node(data);
Node* firstNode = _head->_next;//第一个节点
//构建第一个节点和新节点的链接
newNode->_next = firstNode;
firstNode->_prev = newNode;
//构建新节点和头节点的链接
_head->_next = newNode;
newNode->_prev = _head;
_sz++;
}
void pop_front()
{
assert(!empty());//不能为空
Node* firstNode = _head->_next;
Node* secondNode = firstNode->_next;//第二个节点
//构建第二个节点和头节点的关系
secondNode->_prev = _head;
_head->_next = secondNode;
_sz--;
delete firstNode;
}
iterator insert(iterator pos, const T& data = T())
{
Node* cur = pos._node;//要插入节点的位置
Node* prev = cur->_prev;//要插入节点的上一个位置
Node* newNode = new Node(data);
//构建新节点和要插入节点的位置链接
newNode->_next = cur;
cur->_prev = newNode;
//构建新节点和要插入节点的上一个位置链接
newNode->_prev = prev;
prev->_next = newNode;
_sz++;
return iterator(newNode);//返回插入节点的迭代器
}
iterator erase(iterator pos)
{
assert(!empty());//不能为空
assert(pos != end());//不能删哨兵位节点
Node* cur = pos._node;//要删除节点的位置
Node* next = cur->_next;//要删除节点的下一个位置
Node* prev = cur->_prev;//要删除节点的上一个位置
//构建下一个位置和上一个位置的链接
prev->_next = next;
next->_prev = prev;
delete cur;
_sz--;
return iterator(next);//返回删除节点的下一个位置
}
size_t size()const
{
return _sz;
}
void clear()//清除链表上的所有节点
{
Node* cur = _head->_next;
while (cur != _head)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
//首尾相连,符合双链表的形态
_head->_next = _head;
_head->_prev = _head;
_sz = 0;
}
void swap(List<T>& lt)
{
if (< == this)//比的是地址避免自赋
return;
std::swap(_head, lt._head);
std::swap(_sz, lt._sz);
}
List<T>& operator=(List<T> lt)
{
swap(lt);
return *this;
}
private:
Node* _head;//哨兵位头节点
size_t _sz;//统计链表上节点的个数
};
cpp
#pragma once
template<typename Iterator, class Ref, class Ptr>
struct reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> Self;
reverse_iterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
Iterator tmp = _it;
return *(--tmp);
}
Ptr operator->()
{
return &(operator*());
}
Self& operator++()
{
--_it;
return *this;
}
Self operator++(int)
{
Self tmp(*this);
--_it;
return tmp;
}
Self& operator--()
{
++_it;
return *this;
}
Self operator--(int)
{
Self tmp(*this);
++_it;
return tmp;
}
bool operator!=(const Self& it)const
{
return _it != it._it;
}
bool operator==(const Self& it)const
{
return _it == it._it;
}
public:
Iterator _it;
};
五.list和vector的对比
好了关于list就到这里吧,其实学习list最主要是再次帮助我们理解迭代器相关的知识!
