前言
其实STL里的list就是一个带头双向循环链表,实现起来并不是很困难,我们关键要理解,这里list的迭代器实现,同时和反向迭代器复用正向迭代器实现的原理即可;
list的结点结构
//链表结点
template<class T>
struct ListNode
{
//构造函数:
ListNode(const T& date = T())
:_Prev(nullptr),
_Next(nullptr),
_date(date)
{}
ListNode<T>* _Prev;
ListNode<T>* _Next;
T _date;
};
双向链表的结点结构,没什么好说的;
list的正向迭代器设计:
对于list的迭代器,它本质是一个指针,但是它是通过对象去封装这个指针的,然后这个迭代器对象里面完成指针一样的功能:加加 减减 取地址 解引用 -> != == 等操作;
只要我们的迭代器内部重载这些函数即可完成同样的功能;
但是有个很重要的话题,如何设计出const迭代器和非const迭代器呢?
有一个办法就是const迭代器和非const迭代器都写一份自己的模板代码出来;
但是这样就会又大量的冗余代码,也就是++ – != 和 = = 这些操作都是一模一样的;
我们const迭代器和非const迭代器最大不同点在于,const迭代器不可以修改其执行的值,也就是从代码角度,const迭代器 解引用重载是不可以修改的;
所以我们会在非const的模板基础上,再次传入多一个类型参数,Ref,表示根据传入的是const 还是非const的数据,自动根据类型变通;这样就复用一份代码,设计出了const迭代器和非const迭代器;
同理我们重载 ->依旧为了区分const指针和非const指针,可以通过第三个模板参数Ptr来根据具体传入的类型来选择;达到复用性
//这个迭代器是给list容器里面使用的;
//第二个模板参数的巧妙在于:
//通过传该引用:可以传const 和 非 const 的类型过去
//这样一份代码解决了const 和 非 const 的问题
template<class T,class Ref,class Ptr>
struct __list_iterator
{
typedef ListNode<T> Node;
//构造函数
__list_iterator(Node* p) :_node(p)
{}
// it !=it.end()
bool operator!=(const __list_iterator<T,Ref,Ptr>& it) const
{
return _node != it._node;
}
bool operator ==(const __list_iterator<T, Ref, Ptr>& it) const
{
return _node == it._node;
}
Ref operator*()
{
return _node->_date;
}
Ptr operator->()
{
return &_node->_date;
}
//++it 等价 it.operator++()
__list_iterator<T, Ref, Ptr> operator++()
{
_node = _node->_Next;
return *this;
}
__list_iterator<T, Ref, Ptr> operator++(int)
{
__list_iterator<T, Ref, Ptr> temp(*this);
++*this;
return temp;
}
//--it
__list_iterator<T, Ref, Ptr> operator--()
{
_node = _node->_Prev;
return *this;
}
__list_iterator<T, Ref, Ptr> operator--(int)
{
__list_iterator<T, Ref, Ptr> temp(*this);
--*this;
return temp;
}
//成员数据
Node* _node;
};
list的反向迭代器的设计
list的反向迭代器,实现原理就是正向迭代器的不同操作罢了,只不过是,反向迭代器的++就是正向迭代器的–,
反向迭代器的–就是正向迭代器的++;
我们依旧可以单独出一个模板出来,传入一个任意容易迭代器类型,这样达到了反向迭代器的复用;
#pragma once
namespace xjh{
//这个反向迭代器可以是任意类型的迭代器
//这个反向迭代器就是传入正向迭代器的类型来完成功能的
template<class Iterator,class Ref,class Ptr>
struct reverse_iterator
{
public:
reverse_iterator(Iterator it) :_it(it){}
//这个返回*--temp的原因是:在rbegin()和rend()的设计上,为了对称begin()和end()
Ref& operator*()
{
Iterator temp = it;
return *--temp;
}
Ptr operator->()
{
return &(operator*());
}
reverse_iterator<Iterator, Ref, Ptr>& operator++()
{
--_it;
return *this;
}
reverse_iterator<Iterator, Ref, Ptr> operator++(int)
{
Iterator temp(*this);
--*this;
return temp;
}
reverse_iterator<Iterator, Ref, Ptr>& operator--()
{
++_it;
return*this;
}
reverse_iterator<Iterator, Ref, Ptr> operator--(int)
{
Iterator temp(*this);
++*this;
return temp;
}
bool operator!=(const reverse_iterator<Iterator, Ref, Ptr>& rit)const
{
return _it != rit.it;
}
bool operator==(const reverse_iterator<Iterator, Ref, Ptr>& rit)const
{
return _it == rit.it;
}
//数据类型,其实就是正向迭代器这个类型
protected:
Iterator _it;
};
}
list模拟实现的代码
#pragma once
#include<assert.h>
#include"reverse_iterator.h"
namespace xjh
{
//链表结点
template<class T>
struct ListNode
{
//构造函数:
ListNode(const T& date = T())
:_Prev(nullptr),
_Next(nullptr),
_date(date)
{}
ListNode<T>* _Prev;
ListNode<T>* _Next;
T _date;
};
//这个迭代器是给list容器里面使用的;
//第二个模板参数的巧妙在于:
//通过传该引用:可以传const 和 非 const 的类型过去
//这样一份代码解决了const 和 非 const 的问题
template<class T,class Ref,class Ptr>
struct __list_iterator
{
typedef ListNode<T> Node;
//构造函数
__list_iterator(Node* p) :_node(p)
{}
// it !=it.end()
bool operator!=(const __list_iterator<T,Ref,Ptr>& it) const
{
return _node != it._node;
}
bool operator ==(const __list_iterator<T, Ref, Ptr>& it) const
{
return _node == it._node;
}
Ref operator*()
{
return _node->_date;
}
Ptr operator->()
{
return &_node->_date;
}
//++it 等价 it.operator++()
__list_iterator<T, Ref, Ptr> operator++()
{
_node = _node->_Next;
return *this;
}
__list_iterator<T, Ref, Ptr> operator++(int)
{
__list_iterator<T, Ref, Ptr> temp(*this);
++*this;
return temp;
}
//--it
__list_iterator<T, Ref, Ptr> operator--()
{
_node = _node->_Prev;
return *this;
}
__list_iterator<T, Ref, Ptr>& operator--(int)
{
__list_iterator<T, Ref, Ptr> temp(*this);
--*this;
return temp;
}
//成员数据
Node* _node;
};
template<class T>
class list
{
typedef ListNode<T> Node;
public:
typedef __list_iterator<T,T&,T*> iterator;
typedef __list_iterator<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;
public:
//构造函数
list()
{
_head = new Node;
_head->_Next = _head;
_head->_Prev = _head;
}
list(int n, const T& val = T())
{
_head = new Node;
_head->_Next = _head;
_head->_Prev = _head;
for (int i = 0; i < n; ++i)
{
push_back(val);
}
}
//区间构造
template<class InputIterator>
list(InputIterator first, InputIterator last)
{
_head = new Node;
_head->_Next = _head;
_head->_Prev = _head;
while (first != last)
{
push_back(*first);
++first;
}
}
//传统的拷贝构造和赋值
/*list(const list<T>& lt)
{
list();
for (auto& e : lt)
{
push_back(e);
}
}
list<T>& operator=(const list<T>& lt)
{
if (this != <)
{
clear();
for (auto& e : lt)
{
push_back(e);
}
}
return *this;
}*/
//现代版的拷贝构造和赋值
list(const list<T>& lt)
{
_head = new Node;
_head->_Next = _head;
_head->_Prev = _head;
list<T> temp(lt.begin(), lt.end());
std::swap(_head, temp._head);
}
list<T>& operator== (list<T> lt)
{
std::swap(_head, lt._head);
return *this;
}
//尾插尾删头插头删
void push_back(const T& x)
{
insert(end(), x);
}
void push_front(const T& x)
{
insert(begin(), x);
}
void pop_back()
{
erase(--end());
}
void pop_front()
{
erase(begin());
}
//pos前面插入一个数据
iterator insert(iterator pos, const T& x)
{
Node* newNode = new Node(x);
Node* cur = pos._node;
Node* prev = cur->_Prev;
prev = newNode;
newNode->_Prev = prev;
cur->_Prev = newNode;
newNode->_Next = cur;
return iterator(newNode);
}
iterator erase(iterator pos)
{
assert(pos != end());
Node* prev = pos._node->_Prev;
Node* next = pos._node->_Next;
delete pos._node;
prev->_Next = next;
next->_Prev = prev;
return iterator(next);
}
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());
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
//清除结点,头结点还保存
/*void clear()
{
iterator it = begin();
while (it != end())
{
iterator pos = it++;
delete pos._node;
}
_head->_Next = _head;
_head->_Prev = _head;
}*/
void clear()
{
iterator it = begin();
while (it != end())
{
erase(it++);
}
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
private:
Node* _head;
};
}