文章目录
以后有时间会更新其它成员函数
ListNode__3">1.ListNode 结构体
template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}};
Listtypedef_20">2.List成员变量与typedef
private:Node* _head;size_t _size;
typedef ListNode<T> Node;public://typedef ListIterator<T> iterator;//typedef ListConstIterator<T> const_iterator;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;
3.迭代器iterator
template<class T, class Ref, class Ptr>struct ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;ListIterator(Node* node):_node(node){}// *it//T& operator*()Ref operator*(){return _node->_data;}// it->//T* operator->()//编译器为了可读性,省略了一个-> // it->_a1 <==> it.operator->()->a1Ptr operator->(){return &_node->_data;}// ++itSelf& 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;}};
4.begin()、end()、size()、empty()、构造函数
iterator begin(){return _head->_next;}iterator end(){return _head;}//这里的iterator是自定义类型,不是指针// const迭代器,需要是迭代器不能修改,还是迭代器指向的内容?// 迭代器指向的内容不能修改!const iterator不是我们需要const迭代器//const iterator 是不能修改iterator,而我们要的是it指向的内容不能修改// T* const p1// const T* p2const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}size_t size() const{return _size;}bool empty(){return _size == 0;}
5. insert()、erase()
void insert(iterator pos, const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;// prev newnode cur;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);}
6.push_back()、pop_back()、push_front()、pop_front()
//由于传递引用是类似传递指针的方式,因此不会触发拷贝构造,// 因此函数执行的效率会变高。// 如果你不想在函数中改变引用的值,最佳的实践是加上constvoid push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}
7.拷贝构造、赋值、析构
// lt2(lt1)list(const list<T>& lt){cout << "copy<<'\n";empty_init();for (auto& e : lt){push_back(e);}}// 需要析构,一般就需要自己写深拷贝// 不需要析构,一般就不需要自己写深拷贝,默认浅拷贝就可以void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}//赋值构造可优化为拷贝构造// lt1 = lt3list<T>& operator=(list<T> lt){swap(lt);return *this;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;}
8.总代码
template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}};//内部类 或者 typedef// typedef ListIterator<T, T&, T*> iterator;// typedef ListIterator<T, const T&, const T*> const_iterator;// Ref表示引用,Ptr表示指针template<class T, class Ref, class Ptr>struct ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;ListIterator(Node* node):_node(node){}// *it//T& operator*()Ref operator*(){return _node->_data;}// it->//T* operator->()//编译器为了可读性,省略了一个-> // it->_a1 <==> it.operator->()->a1Ptr operator->(){return &_node->_data;}// ++itSelf& 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>//struct ListConstIterator//{// typedef ListNode<T> Node;// typedef ListConstIterator<T> Self;// Node* _node;// ListConstIterator(Node* node)// :_node(node)// {}// // *it// const T& operator*()// {// return _node->_data;// }// // it->// const T* operator->()// {// return &_node->_data;// }// // ++it// 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 ListNode<T> Node;public://typedef ListIterator<T> iterator;//typedef ListConstIterator<T> const_iterator;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;// const T 类型不可修改本身的值// // const int &ref=x;// 这段代码声明了一个常量引用ref,它引用了前面定义的整型常量x。// 因为是常量引用,所以不能通过ref修改x的值// // int y = 20;// const int* ptr = &y; // 指向常量的指针//这段代码声明了一个整型变量y,然后声明了一个指向整型常量的指针ptr,//它指向了变量y。因为ptr是指向常量的指针,所以不能通过ptr修改y的值。// //iterator begin()//{// //return iterator(_head->_next);// iterator it(_head->_next);// return it;//}iterator begin(){return _head->_next;}iterator end(){return _head;}//这里的iterator是自定义类型,不是指针// const迭代器,需要是迭代器不能修改,还是迭代器指向的内容?// 迭代器指向的内容不能修改!const iterator不是我们需要const迭代器//const iterator 是不能修改iterator,而我们要的是it指向的内容不能修改// T* const p1// const T* p2const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}// lt2(lt1)list(const list<T>& lt){cout << "copy<<'\n";empty_init();for (auto& e : lt){push_back(e);}}// 需要析构,一般就需要自己写深拷贝// 不需要析构,一般就不需要自己写深拷贝,默认浅拷贝就可以void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}//赋值构造可优化为拷贝构造// lt1 = lt3list<T>& operator=(list<T> lt){swap(lt);return *this;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}~list(){clear();delete _head;_head = nullptr;}/*void push_back(const T& x){Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;}*///由于传递引用是类似传递指针的方式,因此不会触发拷贝构造,// 因此函数执行的效率会变高。// 如果你不想在函数中改变引用的值,最佳的实践是加上constvoid push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}void insert(iterator pos, const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;// prev newnode cur;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);}size_t size() const{return _size;}bool empty(){return _size == 0;}private:Node* _head;size_t _size;};