目录
1.模拟代码全部
2.四大块代码理解
1.最底层:ListNode部分
2.第二层:ListIterator部分
3.第三层:ReserveListIterator部分
4最终层:List
1.模拟代码全部
using namespace std;
template<class T>
struct ListNode
{T _Val;ListNode<T>* Prev;ListNode<T>* Next;ListNode(T Val=T()){Prev = nullptr;Next = nullptr;_Val = Val;}
};
template<class T, class Ref, class Ptr>
class ListIterator
{
public:typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;typedef Ref Ref;typedef Ptr Ptr;ListIterator(Node* _NODE = nullptr) :_node(_NODE){}Ptr operator->(){return &(operator*());}Ref operator*(){return _node->_Val;}Self& operator++(){_node = _node->Next;return *this;}Self operator++(int){Node* Newnode = _node;_node = _node->Next;return Newnode;}Self& operator--(){_node = _node->Prev;return *this;}Self operator--(int){Node* Newnode = _node;_node = _node->Prev;return Newnode;}bool operator==(const Self& I) const{if (I._node == _node){return true;}else{return false;}}bool operator!=(const Self& I)const{if (I._node != _node){return true;}else{return false;}}Node* _node;
};
template<class Iterator>
class ReserveListIterator
{
public:typedef typename Iterator::Ptr Ptr;typedef typename Iterator::Ref Ref;typedef ReserveListIterator<Iterator> Self;ReserveListIterator(Iterator it):_it(it){}Ref operator*(){Iterator temp(_it);temp--;return *temp;}Ptr operator->(){return &(operator*());}Self operator++(){_it++;return *this;}Self operator++(int){Iterator temp(_it);_it++;return *temp;}Self operator--(){_it--;return *this;}Self operator--(int){Iterator temp(_it);_it--;return *temp;}bool operator == (const Self & I) const{if (I._it==_it){return true;}else{return false;}}bool operator !=(const Self& I)const{if (I._it != _it){return true;}else{return false;}}Iterator _it;
};
template<class T>
class List
{typedef ListNode<T> Node;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;typedef ReserveListIterator<iterator> reverse_iterator;typedef ReserveListIterator<const_iterator> const_reverse_iterator;
public:List(){creathead();}List(int n,const T& Value=T()){creathead();for (int i = 0; i < n; i++){push_back(Value);}}template <class Iterator>List(Iterator first, Iterator last){creathead();while (first != last){push_back(*first);first++;}}List(const List<T>& l){creathead();List<T>temp(l.begin(), l.end());this->swap(temp);}List<T>& operator=(List<T> l){List<T>temp(l);this->swap(temp);return *this;}~List(){clear();delete _head;_head = nullptr;}iterator begin(){return _head->Next;}iterator end(){return _head;}const_iterator begin()const{return _head->Next;}const_iterator end()const{return _head;}reverse_iterator rbegin(){return reverse_iterator(begin());}reverse_iterator rend(){return reverse_iterator(end());}const_reverse_iterator rbegin()const{return const_reverse_iterator(begin());}const_reverse_iterator rend()const{return const_reverse_iterator(end());}size_t size()const{size_t num = 0;Node* CUR = _head->Next;while (CUR != _head){num++;CUR = CUR->Next;}return num;}bool empty()const{if (begin() == end()){return true;}else{return false;}}void resize(size_t newsize, const T& data = T()){if (newsize > size()){Node* it = end();it = it->Prev;for (size_t i = size(); i < newsize; i++){Node* cur = new Node(data);cur->Next = it->Next;cur->Prev = it;it->Next = cur;}}else{Node* it = end();size_t len = size() - newsize;while (len--){Node* cur = it;it = it->Prev;delete cur;}it->Next = _head;_head->Prev = it;}}T& front(){return *begin();}const T& front()const{return *begin();}T& back(){iterator it = end();it--;return *it;}const T& back()const{iterator it = end();it--;return *it;}void push_back(const T& val){Node* Newnode = new Node(val);Node* cur = _head->Prev;cur->Next = Newnode;_head->Prev = Newnode;Newnode->Next = _head;Newnode->Prev = cur;}void pop_back(){Node* cur = _head->Prev->Prev;Node* popnode = _head->Prev;cur->Next = _head;_head->Prev = cur;delete popnode;}void push_front(const T& val){Node* cur = _head->Next;Node* newnode = new Node(val);_head->Next = newnode;cur->Prev = newnode;newnode->Next = cur;newnode->Prev = _head;}void pop_front(){Node* cur = _head->Next->Next;Node* popnode = _head->Next;_head->Next = cur;cur->Prev = _head;delete popnode;}iterator insert(iterator pos, const T& val){Node* pre = pos._node->Prev;Node* nect = pos._node;Node* newnode = new Node(val);newnode->Prev = pre;newnode->Next = nect;pre->Next = newnode;nect->Prev = newnode;return newnode;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->Prev;Node* next = cur->Next;delete cur;prev->Next = next;next->Prev = prev;return next;}void clear(){size_t sz = this->size();while (sz--){Node* cur = _head->Next;Node* pop;}}void swap(List<T>& l){Node* temp = l._head;l._head = _head;_head = temp;}void creathead(){_head = new Node(0);_head->Prev = _head;_head->Next = _head;}
private:Node* _head;
};
2.四大块代码理解
代码一共分为四块,我们分开来理解
1.最底层:ListNode部分
这里是最简单的部分,小伙伴们应该都看的懂吧
using namespace std;
template<class T>
struct ListNode
{T _Val;ListNode<T>* Prev;ListNode<T>* Next;ListNode(T Val=T()){Prev = nullptr;Next = nullptr;_Val = Val;}
};
这里我们形象点记忆
其实应该不用赘述多了,基础好的同学看到这张图应该就差不多懂了。
唯一要注意的是
T Val=T()
>> T()表示对类型T进行值初始化,生成一个临时的右值
>> 如果T是内置类型(如int,double,char等),则T()会执行零初始化,即返回0,0.0或'\0'等默认值。
>> 如果T是类类型,则T()会调用默认构造函数(如果存在)
聪明的小伙伴已经理解清楚了
2.第二层:ListIterator部分
聪明的小伙伴应该看代码就能懂了
那么我在这下方陈述了一些难点和易错点
template<class T, class Ref, class Ptr>
class ListIterator
{
public:typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;typedef Ref Ref;typedef Ptr Ptr;ListIterator(Node* _NODE = nullptr) :_node(_NODE){}Ref operator*(){return _node->_Val;}Self& operator++(){_node = _node->Next;return *this;}Self operator++(int){Node* Newnode = _node;_node = _node->Next;return Newnode;}Self& operator--(){_node = _node->Prev;return *this;}Self operator--(int){Node* Newnode = _node;_node = _node->Prev;return Newnode;}bool operator==(const Self& I) const{if (I._node == _node){return true;}else{return false;}}bool operator!=(const Self& I)const{if (I._node != _node){return true;}else{return false;}}Node* _node;
};
聪明的小伙伴应该看代码就能懂了
那么我在这陈述一下一些难点和易错点
>> typedef Ref Ref和typedef Ptr Ptr,简单来说,我们需要让编译器知道Listiterator里面有Ptr和 Ref,后面的反向迭代器ReserveListIterator来使用Listiterator的Ref和Ptr
>> Ref:Ref在后面我们会通过T&来填充这块模板,也就是说Ref就是引用
>> Ptr:Ptr在后面我们会通过T*来填充这块模板,也就是说Ptr就是指针
3.第三层:ReserveListIterator部分
聪明的小伙伴直接看代码
template<class Iterator>
class ReserveListIterator
{
public:typedef typename Iterator::Ptr Ptr;typedef typename Iterator::Ref Ref;typedef ReserveListIterator<Iterator> Self;ReserveListIterator(Iterator it):_it(it){}Ref operator*(){Iterator temp(_it);temp--;return *temp;}Ptr operator->(){return &(operator*());}Self operator++(){_it++;return *this;}Self operator++(int){Iterator temp(_it);_it++;return *temp;}Self operator--(){_it--;return *this;}Self operator--(int){Iterator temp(_it);_it--;return *temp;}bool operator == (const Self & I) const{if (I._it==_it){return true;}else{return false;}}bool operator !=(const Self& I)const{if (I._it != _it){return true;}else{return false;}}Iterator _it;
};
>> 之前我们在ListIterator里重新定义了Ptr和Ref参数就是留在ReserveListIterator使用
这里要注意一定不要写成Iterator &,本人之前就因为这个错误导致费了1小时/(ㄒoㄒ)/~~
4最终层:List
牛人已经看代码就懂了
template<class T>
class List
{typedef ListNode<T> Node;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;typedef ReserveListIterator<iterator> reverse_iterator;typedef ReserveListIterator<const_iterator> const_reverse_iterator;
public:List(){creathead();}List(int n,const T& Value=T()){creathead();for (int i = 0; i < n; i++){push_back(Value);}}template <class Iterator>List(Iterator first, Iterator last){creathead();while (first != last){push_back(*first);first++;}}List(const List<T>& l){creathead();List<T>temp(l.begin(), l.end());this->swap(temp);}List<T>& operator=(List<T> l){List<T>temp(l);this->swap(temp);return *this;}~List(){clear();delete _head;_head = nullptr;}iterator begin(){return _head->Next;}iterator end(){return _head;}const_iterator begin()const{return _head->Next;}const_iterator end()const{return _head;}reverse_iterator rbegin(){return reverse_iterator(begin());}reverse_iterator rend(){return reverse_iterator(end());}const_reverse_iterator rbegin()const{return const_reverse_iterator(begin());}const_reverse_iterator rend()const{return const_reverse_iterator(end());}size_t size()const{size_t num = 0;Node* CUR = _head->Next;while (CUR != _head){num++;CUR = CUR->Next;}return num;}bool empty()const{if (begin() == end()){return true;}else{return false;}}void resize(size_t newsize, const T& data = T()){if (newsize > size()){Node* it = end();it = it->Prev;for (size_t i = size(); i < newsize; i++){Node* cur = new Node(data);cur->Next = it->Next;cur->Prev = it;it->Next = cur;}}else{Node* it = end();size_t len = size() - newsize;while (len--){Node* cur = it;it = it->Prev;delete cur;}it->Next = _head;_head->Prev = it;}}T& front(){return *begin();}const T& front()const{return *begin();}T& back(){iterator it = end();it--;return *it;}const T& back()const{iterator it = end();it--;return *it;}void push_back(const T& val){Node* Newnode = new Node(val);Node* cur = _head->Prev;cur->Next = Newnode;_head->Prev = Newnode;Newnode->Next = _head;Newnode->Prev = cur;}void pop_back(){Node* cur = _head->Prev->Prev;Node* popnode = _head->Prev;cur->Next = _head;_head->Prev = cur;delete popnode;}void push_front(const T& val){Node* cur = _head->Next;Node* newnode = new Node(val);_head->Next = newnode;cur->Prev = newnode;newnode->Next = cur;newnode->Prev = _head;}void pop_front(){Node* cur = _head->Next->Next;Node* popnode = _head->Next;_head->Next = cur;cur->Prev = _head;delete popnode;}iterator insert(iterator pos, const T& val){Node* pre = pos._node->Prev;Node* nect = pos._node;Node* newnode = new Node(val);newnode->Prev = pre;newnode->Next = nect;pre->Next = newnode;nect->Prev = newnode;return newnode;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->Prev;Node* next = cur->Next;delete cur;prev->Next = next;next->Prev = prev;return next;}void clear(){size_t sz = this->size();while (sz--){Node* cur = _head->Next;Node* pop;}}void swap(List<T>& l){Node* temp = l._head;l._head = _head;_head = temp;}void creathead(){_head = new Node(0);_head->Prev = _head;_head->Next = _head;}
private:Node* _head;
};
这里要注意一下转换顺序,listnode不能直接转换为reverse_iterator
listnode转换为reverse_iterator需要两个个过程
易错点难点就是以上那么多了,说多了只会妨碍小伙伴们,通过自己学习效率才是最高的。
3.测试代码
#include"LList.h"
#include<iostream>
void ListPrint(List<int> it)
{auto i = it.begin();while(i!=it.end()){cout << *i << " ";i++;}
}
void TestBiteList1()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };List<int> l3(array, array + sizeof(array) / sizeof(array[0]));ListPrint(l3);ListIterator<int, int&, int*> it(l3.begin());}
void TestBiteList2()
{List<int> l;l.push_back(1);l.push_back(2);l.push_back(3);ListPrint(l);l.pop_back();l.pop_back();ListPrint(l);l.pop_back();cout << l.size() << endl;l.push_front(1);l.push_front(2);l.push_front(3);ListPrint(l);l.pop_front();l.pop_front();ListPrint(l);l.pop_front();cout << l.size() << endl;
}
void TestBiteList3()
{int array[] = { 1, 2, 3, 4, 5 };List<int> l(array, array + sizeof(array) / sizeof(array[0]));auto pos = l.begin();l.insert(l.begin(), 0);ListPrint(l);++pos;l.insert(pos, 2);ListPrint(l);l.erase(l.begin());l.erase(pos);ListPrint(l);cout << *pos << endl;auto it = l.begin();while (it != l.end()){it = l.erase(it);}cout << l.size() << endl;
}
void TestBiteList4()
{int array[] = { 1, 2, 3, 4, 5 };List<int> l(array, array + sizeof(array) / sizeof(array[0]));auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;const List<int> cl(l);auto crit = l.rbegin();while (crit != l.rend()){cout << *crit << " ";++crit;}cout << endl;
}
int main()
{TestBiteList1();TestBiteList2();TestBiteList3();TestBiteList4();
}