list实质上就是双向链表,用法和vector、string差不多

- int main()
- {
- list<int> lt1;
- lt1.push_back(1);
- lt1.push_back(2);
- lt1.push_back(3);
- lt1.push_front(0);
-
- //遍历
-
- //迭代器
- list<int>::iterator it = lt1.begin();
- //这里用"!=",是因为end位置是在头哨兵位
- while (it != lt1.end())
- {
- cout << *it << " ";
- it++;
- }
- cout << endl;
-
-
- //范围for
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
-
- //反向迭代器
- //list
::reverse_iterator rit = lt1.rbegin(); - auto rit = lt1.rbegin();
- while (rit != lt1.rend())
- {
- cout << *rit << " ";
- rit++;
- }
- cout << endl;
-
- lt1.pop_front();
- lt1.pop_back();
-
- for (auto e : lt1)
- {
- cout << e << " ";
- }
- cout << endl;
- }
- namespace Cris
- {
- //节点
- template<class T>
- struct list_node
- {
- list_node
* _next; - list_node
* _prev; - T _data;
-
- list_node(const T& val = T())
- :_next(nullptr)
- ,_prev(nullptr)
- ,_data(val)
- {}
- };
-
-
- //迭代器
-
- // typedef __list_iterator
iterator; - // typedef __list_iterator
const_iterator; - template<class T, class Ref, class Ptr>
- struct _list_iterator
- {
- typedef list_node
Node; - typedef _list_iterator
self; - Node* _node;
-
- _list_node(Node* node)
- :_node(node)
- {}
-
- //析构函数 -- 节点不属于迭代器,不需要迭代器释放
- //拷贝构造和赋值重载 -- 默认生成的浅拷贝
-
- Ref operator* ()
- {
- return _node->_data;
- }
-
- Ptr operator->()
- {
- 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;
- }
- };
-
- //链表
- template<class T>
- class list
- {
- typedef list_node<int> Node;
- public:
- typedef _list_node
iterator; - typedef _list_node
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();
- _hend->next = _head;
- _head->_prev = _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;
- }
- }
-
- void swap(list
& lt) - {
- std::swap(_head, lt._head);
- }
-
- //lt2(lt1) 现代写法
- list(const list
& lt) - {
- empty_init();
- list
tmp(lt.begin(), lt.end()) ; - swap(tmp);
- }
-
- //lt2 = lt1
- list
& operator=(list lt) - {
- swap(lt);
- return *this;
- }
-
- ~list()
- {
- clear();
- delete _head;
- _head = nullptr;
- }
-
- void clear()
- {
- iterator it = begin();
- while (it != end())
- {
- it = erase(it);
- }
- }
-
- void push_back(const T& x)
- {
- /*Node* tail = _head->_prev;
- Node* newnode = new Node(x);
- tail->_next = newnode;
- newnode->_prev = tail;
- newnode->_next = _head;
- _head->_prev = newnode;*/
-
- insert(end(), x);
- }
-
- void push_front(const T& x)
- {
- insert(begin(), x);
- }
-
- void pop_back()
- {
- //end() 是头哨兵位,--就是list的尾
- 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->_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);
- }
-
- private:
- Node* _head;
-
- };
- }
因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,7,8,9 };
- Cris::list<int> lt(arr, arr + (sizeof(arr) / sizeof(arr[0])));
-
- auto it = lt.begin();
- while (it != lt.end())
- {
- //erase()函数执行后,it所指向的节点已被删除
- //因此it无效,在下一次使用it时,必须先给其赋值
- it = lt.erase(it);
- }
-
- return 0;
- }
