list是和vector类似的顺序型容器,也是是比vector更为复杂的容器。list是双向带头链表,初始有一个不存数据的头节点,并通过节点内指针将后续节点依次连接起来 。
相较于vector,list特点如下:
(1)list可以按需申请,释放不需要扩容操作,减少内存碎片。
(2)任意位置插入删除的效率是O(1)。
(3)不支持下标随机访问。
(4)cache缓存命中率低。
list结构较为复杂,就list节点来说,list自己本身和list节点不是一样的结构,list包含list节点,因此需要分开设计。
#include<iostream>
using namespace std;namespace YHY
{// List的节点类template<class T>struct ListNode{ListNode(const T& val = T()){_val = val;}ListNode<T>* _pPre = nullptr;ListNode<T>* _pNext = nullptr;T _val;};//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){}ListIterator(const Self& l){_pNode = l._pNode;}Ref operator*(){return _pNode->_val;}T* operator->(){return &(operator*());}Self& operator++(){_pNode = _pNode->_pNext;return *this;}Self operator++(int){Self old = *this;_pNode = _pNode->_pNext;return old;}Self& operator--(){_pNode = _pNode->_pPre;return _pNode;}Self& operator--(int){Self old = *this;_pNode = _pNode->_pPre;return old;}bool operator!=(const Self& l){return _pNode != l._pNode;}bool operator==(const Self& l) //比较的是节点地址而不是节点内数据,因为比较节点内数据没意义,只有比较地址可以进行遍历的操作{return _pNode == l._pNode;}PNode _pNode;};//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;public:// List的构造list(){CreateHead();}list(int n, const T& value = T()){CreateHead();for (int i = 0; i < n; i++){push_back(value);}}template <class Iterator>list(Iterator first, Iterator last){CreateHead();while (first != last){push_back(*first);first++;}}list(const list<T>& l){CreateHead();for (auto e : l){push_back(e);}}list<T>& operator=(const list<T> l){CreateHead();list(l.begin(), l.end());return *this;}~list(){clear();delete _pHead;_pHead = nullptr;}// List Iteratorconst_iterator begin() const{ return const_iterator(_pHead->_pNext);}const_iterator end() const{ return const_iterator(_pHead); }iterator begin() { return iterator(_pHead->_pNext); }iterator end() { return iterator(_pHead); }size_t size() const{size_t sum = 0;const_iterator it = begin();while (it != end()){it++;sum++;}return sum; }bool empty()const{return _pHead->_pNext == _pHead->_pPre;}T& front(){return _pHead->_pNext;}const T& front()const{return _pHead->_pNext;}T& back(){return _pHead->_pPre;}const T& back()const{return _pHead->_pPre;}// List Modifyvoid push_back(const T& val){ insert(end(), val);}void pop_back(){ erase(end());}void push_front(const T& val) { insert(begin(), val); }void pop_front() {erase(begin());}// 在pos位置前插入值为val的节点iterator insert(iterator pos, const T& val){PNode newnode = new Node(val);PNode next = pos._pNode;PNode pre = next->_pPre;pre->_pNext = newnode;newnode->_pPre = pre;next->_pPre = newnode;newnode->_pNext = next;return iterator(newnode);}// 删除pos位置的节点,返回该节点的下一个位置iterator erase(iterator pos){PNode cur = pos._pNode->_pNext;PNode pre = pos._pNode->_pPre;cur->_pNext = pre;pre->_pPre = cur;pos._pNode->_pNext = nullptr;pos._pNode->_pPre = nullptr;delete pos._pNode;return iterator(cur);}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}void swap(list<T>& l){std::swap(_pHead, l._pHead);}private:void CreateHead(){PNode newhead = new Node;_pHead = newhead;_pHead->_pNext = _pHead;_pHead->_pPre = _pHead;}PNode _pHead;};
};