目录
节点初始化
template<class T>
class list_node
{
T _data;
list_node<T>* _next;
list_node<T>* _prev;
//list_node(const T& x)
// :_data(x)
// ,_next(nullptr)
// ,_prev(nullptr)
//{}
list_node(const T& x=T())
:_data(x)
,_next(nullptr)
,_prev(nullptr)
{}
};
迭代器
template<class T>
struct __list_iterator//迭代器
{ //迭代器不需要写析构函数
typedef list_node<T> Node;
typedef __list_iterator iterator;
Node* _node;//节点指针
__list_iterator(Node* node)//构造函数
:_node(node)
{}
bool operator!=(const iterator& it)const
{
return _node != it._node;
}
iterator& operator++()
{
_node = _node->_next;
return *this;
}
iterator& operator++(int)
{
iterator tmp(*this);
_node = _node->next;
return tmp;
}
iterator& operator--()
{
_node = _node->_prev;
return *this;
}
iterator& operator--(int)
{
iterator tmp(*this);
_node = _node->_prev;
return tmp;
}
T& operator*()
{
return _node->_data;
}
T* operator->()
{
return &(operator*());
}
bool operator==(const iterator& it)const
{
return _node == it._node;
}
};
list功能实现
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T> iterator;
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
list()
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
void push_back(const T& x)
{
Node* tail = _head->_prev;
Node* newnode = new Node(x);
// _head tail newnode
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = _head;
_head->_prev = newnode;
}
private:
Node* _head;//哨兵位头节点
};
注意事项
T& operator*() { return _node->_data; } T* operator->() { return &(operator*()); }
当使用->实际是使用了俩次->,编译器进行了优化,不需要我们输入俩次->,输入一次即可
如果这样写会报错
因为形参用const修饰,在调用begin 胡哦end这些成员函数的时候要用const修饰它们,否则会报错,也就是说我只能调用const修饰的函数,此时就需要const迭代器
源代码里面有从上图迭代器
在模板参数里多加俩个参数,使其泛型化,不用像之前那样写T&或T*,那样会写死,现在这种写法你传过来是什么,我就是什么,这样写会更加灵活
这里是const迭代器
insert |erase
iterator insert(iterator pos, const T& x) { Node* cur = pos._node; Node* prev = cur->_prev; Node* newnode = new Node(x); // prev newnode cur prev->_next = newnode; newnode->_prev = prev; newnode->_next = cur; cur->_prev = newnode; return iterator(newnode); }
这里的迭代器是一个了类,并不是简单的指针,只不过这个类里面有个Node*的指针,要访问某个位置,不能用迭代器去直接访问,而是用类里面的指针去访问
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 cur; return iterator(next); }
这种连续插入会出错,我们加上下面四条语句即可
typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef ptrdiff_t difference_type;
析构函数|拷贝构造函数|operator=
我们没写拷贝构造函数,此时进行拷贝构造是浅拷贝
简单析构函数,这里使用clear仅仅用来清理数据(clear之后哨兵位的头节点还存在),因此用delete删除头节点,并释放
~list() { clear();//有隐藏的this delete _head; _head = nullptr; } void clear() { iterator it = begin(); while (it != end()) { it=erase(it);//erase之后这个节点所在的迭代器会失效,就不能进行it++,所以这样写 } }
释放头节点
构造函数用迭代器区间构造,我们这里写了一个模板参数
push_back的前提是链表哨兵位的头节点已经处理好了,但在拷贝构造了里,我们还没有初始化我们的哨兵位头节点
因此我们要初始化哨兵位的头节点,加个函数即可
接下来写拷贝构造,这里由于是链表,交换头节点,就等于全部交换了
void swap(list<T>& x) { std::swap(_head,x._head); } void empty_init() { //创建并初始化哨兵位的头节点 _head = new Node; _head->_next = _head; _head->_prev = _head; } template<class InputIterator> list(InputIterator first, InputIterator last) { empty_init(); while (first != last) { push_back(*first); ++first; } } //lt2(lt1) list(const list<T>& lt) { empty_init();//初始化lt2 list<T> tmp(lt.begin(), lt.end());//定义一个新对象,用迭代器区间构造,lt2刚好想要这个tmp,我们交换即可 swap(tmp);//交换哨兵位头节点,后面的也就跟着交换了 }
这种拷贝为深拷贝
operator=
list<T>& operator=(list<T> lt) { swap(lt); return *this; }
完整代码
namespace myspace
{
template<class T>
struct list_node
{
T _data;
list_node<T>* _prev;
list_node<T>* _next;
//list_node(const T& x)
// :_data(x)
// ,_next(nullptr)
// ,_prev(nullptr)
//{}
list_node(const T& x=T())
:_data(x),
_prev(nullptr),
_next(nullptr)
{}
};
//list_node(const T& x)
// :_data(x)
// ,_next(nullptr)
// ,_prev(nullptr)
//{}
//template<class T,class T&,class T*>
template<class T,class Ref,class Ptr>
struct __list_iterator//迭代器
{ //迭代器不需要写析构函数
typedef list_node<T> Node;
typedef __list_iterator<T,Ref,Ptr> iterator;
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef ptrdiff_t difference_type;
Node* _node;//节点指针
__list_iterator(Node* node)//构造函数
:_node(node)
{}
bool operator!=(const iterator& it)const
{
return _node != it._node;
}
iterator& operator++()
{
_node = _node->_next;
return *this;
}
iterator& operator++(int)
{
iterator tmp(*this);
_node = _node->_next;
return tmp;
}
iterator& operator--()
{
_node = _node->_prev;
return *this;
}
iterator& operator--(int)
{
iterator tmp(*this);
_node = _node->_prev;
return tmp;
}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operator*());
}
bool operator==(const iterator& it)const
{
return _node == it._node;
}
};
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;
const_iterator begin()const
{
return const_iterator(_head->_next);
}
const_iterator end()const
{
return const_iterator(_head);
}
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
list()
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
void push_back(const T& x)
{
Node* tail = _head->_prev;
Node* newnode = new Node(x);
// _head tail newnode
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = _head;
_head->_prev = newnode;
}
iterator insert(iterator pos, const T& x)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* newnode = new Node(x);
// prev newnode cur
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
return iterator(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 cur;
return iterator(next);
}
void swap(list<T>& x)
{
std::swap(_head,x._head);
}
void empty_init()
{
//创建并初始化哨兵位的头节点
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
template<class InputIterator>
list(InputIterator first, InputIterator last)
{
empty_init();
while (first != last)
{
push_back(*first);
++first;
}
}
//lt2(lt1)
list(const list<T>& lt)
{
empty_init();//初始化lt2
list<T> tmp(lt.begin(), lt.end());//定义一个新对象,用迭代器区间构造,lt2刚好想要这个tmp,我们交换即可
swap(tmp);//交换哨兵位头节点,后面的也就跟着交换了
}
~list()
{
clear();//有隐藏的this
delete _head;
_head = nullptr;
}
void clear()
{
iterator it = begin();
while (it != end())
{
it=erase(it);//erase之后这个节点所在的迭代器会失效,就不能进行it++,所以这样写
}
}
list<T>& operator=(list<T> lt)
{
swap(lt);
return *this;
}
private:
Node* _head;//哨兵位头节点
};
}