一. 定义和成员变量
// List的节点类
template<class T>
struct ListNode
{
ListNode(const T& val= T())
:_val(val)
,_prev(this) //指向之后都要更改的
,_next(this)
{}
ListNode<T>* _prev; //指向前一个节点
ListNode<T>* _next; //指向后一个节点
T _val; //节点数据
};
template<class T>
class list
{
typedef ListNode<T> Node;
typedef Node* PNode;
private:
void CreateHead() //每个构造函数都需要创造哨兵节点, 所以单独创建一个函数调用
{
_pHead = new Node;
}
PNode _pHead = nullptr; //哨兵节点
};
二. 迭代器
由于 List 的数据并不像 Vector, String 一样连续存放的, 为了统一迭代器的使用方式, 所以 List 的迭代器是一个类, 操作符在类中重载的.
//List的迭代器类
template<class T, class Ref, class Ptr>
class ListIterator
{
typedef ListNode<T>* PNode;
typedef ListIterator<T, Ref, Ptr> Self;
public:
//使用节点指针或者无参初始化迭代器
ListIterator(PNode pNode = nullptr)
:_pNode(pNode)
{}
Ref operator*()
{
return _pNode->_val;
}
Ptr operator->()
{
return &(_pNode->_val);
}
Self& operator++()
{
_pNode = _pNode->_next;
return *this;
}
Self operator++(int)
{
Self tmp(*this);
_pNode = _pNode->_next;
return tmp;
}
Self& operator--()
{
_pNode = _pNode->_prev;
return *this;
}
Self operator--(int)
{
Self tmp(*this);
_pNode = _pNode->_prev;
return tmp;
}
bool operator!=(const Self& l)
{
return _pNode != l._pNode;
}
bool operator==(const Self& l)
{
return _pNode == l._pNode;
}
PNode _pNode; //迭代器类的成员, 保存节点的指针
};
为了统一, 在 List 类中 typedef 迭代器
//list类
template<class T>
class list
{
typedef ListNode<T> Node;
typedef Node* PNode;
public:
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, const T&, const T*> const_iterator;
//typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
...
List Iterator
iterator begin()
{
return _pHead->_next;
}
iterator end()
{
return _pHead;
}
const_iterator begin() const
{
return _pHead->_next;
}
const_iterator end() const
{
return _pHead;
}
...
};
三. 默认成员函数
1. 构造函数
//无参构造函数, 只需创造哨兵节点即可
list()
{
CreateHead();
}
//迭代器区间构造函数, 和 vector 一样, 只需将每个数据插入即可
template <class Iterator>
list(Iterator first, Iterator last)
{
CreateHead();
while (first != last)
{
push_back(*first); //push_back() 函数在后面
++first;
}
}
2. 析构函数
~list()
{
//手动释放空间
/*if (_pHead)
{
PNode cur = _pHead->_next;
while (cur != _pHead)
{
cur = cur->_next;
delete (cur->_prev);
}
delete _pHead;
_pHead = nullptr;
}*/
clear(); //调用 clear() 函数释放空间即可
delete _pHead; //释放哨兵节点
_pHead = nullptr;//置空
}
3. 拷贝构造
//拷贝构造
list(const list<T>& l)
{
list<T> tmp(l.begin(), l.end());//利用迭代器区间初始化 tmp 对象
swap(tmp); //使用内置 swap()函数(在下面) 交换即可
}
4. 赋值重载
//赋值重载 复用拷贝构造和 swap() 函数即可
list<T>& operator=(const list<T> l)
{
swap(l);
return *this;
}
四. 其他成员函数
1. 内置 swap
void swap(list<T>& l)
{
std::swap(_pHead, l._pHead); //交换哨兵节点指针即可
}
2. insert()
// 在pos位置前插入节点, 返回新插入的节点
iterator insert(iterator pos, const T& val)
{
PNode new_node = new Node(val); //新节点
PNode cur = pos._pNode; //当前节点
PNode prev = cur->_prev; //前一个节点
//插入节点
prev->_next = new_node;
new_node->_prev = prev;
new_node->_next = cur;
cur->_prev = new_node;
return new_node;
}
4. push_back()
void push_back(const T& val)
{
insert(end(), val); //调用 insert() 即可
}
5. erase()
//删除pos位置的节点, 返回该节点的下一个位置
iterator erase(iterator pos)
{
PNode cur = pos._pNode; //当前节点
PNode prev = cur->_prev; //前一个节点
PNode next = cur->_next; //后一个节点
//前后相连
prev->_next = next;
next->_prev = prev;
delete cur; //释放当前节点空间
return next; //返回后一个节点
}
6. pop_back()
void pop_back()
{
erase(--end()); //调用 erase() 即可
}
7. clear()
void clear()
{
iterator it = begin();
while (it != end()) //释放除哨兵节点以外的所有节点
it = erase(it);
}