迭代器:
namespace my_list
{
//节点类模板
template<class T>
struct Listnode //单个节点(一个链表当然是由许多个节点组成的)
{
Listnode<T>* _next;//指向下一个 T类型的节点
Listnode<T>* _prev;//指向上一个 T类型的节点
T _data; //存储在这个节点里面的数据(数据类型是T);
Listnode<T>( const T& val=T() )//默认构造无论是自定义类型还是内置类型都可以;
//只有头结点使用默认构造;
:_next(nullptr)
,_prev(nullptr)
,_data(val)
{}
};
//迭代器类模板
//利用模板参数实现复用,而不是用多个单独的模板;
template <class T,class Ref,class Ptr>
struct List_iterator
{
typedef Listnode<T> node;
//普通迭代器和const 迭代器的区别就是,普通迭代器指向的元素可以改变;
typedef List_iterator<T,Ref,Ptr> self;
//所有迭代器对象里面都封装了一个节点指针;
node* _node;
//构造函数
List_iterator(node* pointer_node)
:_node(pointer_node)
{}
//因为迭代器是个类,不能直接解引用,所以要对迭代器运算符重载;
Ref operator*()//Ref可能为 const T&或 T
{
return _node->_data;//返回这个节点元素的值或者拷贝;
}
Ptr operator->()//Ptr可能为 const T* 或 T*
{
//针对自定义类型(_data是一个结构体,想要访问里面的成员变量)
return &(_node->_data);//返回指向这个节点元素(一个结构体)的指针;
}
//前置++(返回值为迭代器对象的引用)
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)
{
return _node != it._node;//用这个迭代器对象里面的指向节点的指针来与另一个迭代器对象里面的指向节点的指针比较;
}
bool operator==(const self& it)
{
return _node == it._node;//用这个迭代器对象里面的指向节点的指针来与另一个迭代器对象里面的指向节点的指针比较;
}
};
list:
//双向带头循环链表
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<iterator, T&, T*> reverse_iterator;
typedef Reverse_Iterator<iterator, const T&,const T*> const_reverse_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());//因为反向迭代器rbegin()需要正向迭代器end()构造,原生指针迭代器或者正向迭代器对象都可以;
}
const_reverse_iterator rend()
{
return const_reverse_iterator(begin());//因为反向迭代器rend()需要正向迭代器begin()构造;
}
List()//构造函数
{
empty_init();
}
//区间构造
template<class InputIterator>
List(InputIterator first, InputIterator last)
{
empty_init();
while (first != last)
{
push_back(*first);
++first;
}
}
//拷贝构造
List(const List<T>& lt)
{
//传统写法
/*empty_init();
iterator it = lt.begin();
while (it!=lt.end())
{
push_back(*it);
++it;
}*/
//现代写法
empty_init();
List<T> tmp(lt.begin(), lt.end());
swap(tmp);
}
//赋值
List<T>& operator=(const List<T> x)//此处利用拷贝构造,直接窃取革命果实;
{
swap(x);
return *this;
}
bool empty()
{
return begin() == end();
}
void push_front(const T& val)
{
insert(begin(),val);
}
void push_back(const T& val)
{
insert(end(),val);
}
void insert(iterator pos,const T& val)
{
node* cur = pos._node;
node* prev = cur->_prev;
node* newnode = new node(val);
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
prev->_next = newnode;
}
iterator erase(iterator pos)
{
assert(pos!=end());
node* cur = pos._node;
node* prev = cur->_prev;
node* next = cur->_next;
prev->_next = next;
next->_prev = prev;
//防止内存泄漏
delete pos._node;
return iterator(next);
}
void pop_back()
{
erase(end());
}
void pop_front()
{
erase(begin());
}
void empty_init()
{
_head = new node;
_head->_next = _head;
_head->_prev = _head;
}
void swap(List<T>& tmp)
{
std::swap(_head,tmp._head);//这里只是交换了两个变量的值;
}
//析构函数
~List()
{
clear();
delete _head;
_head = nullptr;
}
//清除
void clear()
{
iterator it = begin();
while (it!=end())
{
it=erase(it);
}
}
private:
node* _head;//头节点指针
};