目录
一、初始准备
二、迭代器
三、构造函数与析构函数
四、插入与删除数据
五、全部代码
一、初始准备
为了防止与库里的命名发生冲突,所以首先得定义一个命名空间
list是通过一个个节点连接而成的,所以得先定义一个自定义变量,采用模板的方式
这里实现的是带头双向循环链表,所以有前后指针成员,以及数据成员,共三个成员
同时定义构造函数,将其初始化
定义一个list类,同样采用模板,同时将其将要使用的正反迭代器,节点名称用typedef定义一个新名称,将其简化
成员就一个头节点指针
二、迭代器
正向迭代器
迭代器实现,同样采用了模板,但采用了三个模板参数,便于const版本和普通版本的实现,减少代码量,不至于代码冗余
由于list是一个个节点连接而成,空间不连续,无法像vector一样,所以需要通过运算符重载来实现与vector一样的遍历方式,如++、--等等
成员也只有一个节点指针
重载解引用(*)运算符,返回的是节点存储的数据
重载解引用(->)运算符,返回的是节点存储的数据的地址,由于存储的数据是自定义类型时,会有两个->->,为了增加可读性,编译器优化掉了一个箭头
重载前置++,前置--,只需让节点指针指向下一个或上一个节点即可
重载后置++,后置--,需要先拷贝一个迭代器对象(浅拷贝),再让原对象的节点指针指向下一个或上一个节点,然后返回拷贝的对象即可
重载== 、!=运算符,判断节点指针是否相等即可
头节点和尾节点
反向迭代器
这里头尾节点采用与正向迭代器相对称的方式(也可以不这样做)
由于正向迭代器已经实现,复用其中的一些功能即可
只是正向迭代器的++,变成了--,--变成了++,相反而已
三、构造函数与析构函数
默认构造函数,先给头节点开辟一块空间,再将其成员指针都指向头节点即可
其它构造函数
先将其初始化,即创立头节点
再往后尾插数据即可
拷贝构造(深拷贝)
这里需要实现一个迭代器(构造函数)来插入数据,实现一个链表
先将其初始化,即创立头节点
再创建一个临时对象,调用它的构造函数(迭代器)
然后将头节点指针交换即可
赋值运算符重载,这里采用的是值传递,也是为了实现一次拷贝构造,再交换头节点指针
清空链表(头节点除外),调用随机位置节点的删除函数
调用清空数据的函数,然后将头节点空间释放,再置空
四、插入与删除数据
尾插
随机位置节点的插入
随机位置节点的删除
头节点不能删,所以需断言一下
五、全部代码
//List.h #include#include using namespace std; #include"reverse_iterator.h" namespace Henry { template struct ListNode { ListNode * _prev; ListNode * _next; T _data; ListNode(const T& data = T()):_prev(nullptr),_next(nullptr),_data(data) {} }; template struct __list_iterator { typedef __list_iterator self; typedef struct ListNode Node; Node* _node; __list_iterator(Node* x):_node(x) {} 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) const { return _node != it._node; } bool operator==(const self& it) const { return _node != it._node; } }; template class list { public: typedef struct ListNode Node; typedef __list_iterator iterator; typedef __list_iterator const_iterator; typedef __list_reverse_iterator reverse_iterator; typedef __list_reverse_iterator const_reverse_iterator; list() { _head = new Node(); _head->_next = _head; _head->_prev = _head; } reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } iterator begin() { return iterator(_head->_next); } iterator end() { return iterator(_head); } const_iterator begin() const { return const_iterator(_head->_next); } const_iterator end() const { return const_iterator(_head); } template list(InputIterator first, InputIterator last) { _head = new Node(); _head->_prev = _head; _head->_next = _head; while (first != last) { push_back(*first); ++first; } } list(size_t n , const T& val = T()) { _head = new Node(); _head->_next = _head; _head->_prev = _head; for (size_t i = 0; i < n; i++) { push_back(val); } } list(int n, const T& val = T()) { _head = new Node(); _head->_next = _head; _head->_prev = _head; for (int i = 0; i < n; i++) { push_back(val); } } list(const list & lt) { _head = new Node(); _head->_prev = _head; _head->_next = _head; list tmp(lt.begin(), lt.end()); std::swap(_head, tmp._head); } list & operator=(list lt) { std::swap(lt._head, _head); return *this; } void push_back(const T& val) { Node* newnode = new Node(val); Node* tail = _head->_prev; newnode->_next = _head; newnode->_prev = tail; _head->_prev = newnode; tail->_next = newnode; } void pop_back() { erase(--end()); } iterator insert(iterator pos, const T& val) { Node* posprev = pos._node->_prev; Node* newnode = new Node(val); posprev->_next = newnode; pos._node->_prev = newnode; newnode->_prev = posprev; newnode->_next = pos._node; return iterator(newnode); } void clear() { iterator it = begin(); while (it != end()) { erase(it++); } } ~list() { clear(); delete _head; _head = nullptr; } iterator erase(iterator pos) { assert(pos != end()); Node* posprev = pos._node->_prev; Node* posnext = pos._node->_next; delete pos._node; posprev->_next = posnext; posnext->_prev = posprev; return iterator(posnext); } void pop_front() { erase(begin()); } void push_front(const T& x) { insert(begin(),x); } private: Node* _head; }; void print_list(const list & lt) { list ::const_iterator it = lt.begin(); list ::const_iterator tail = lt.end(); while (it != tail) { cout << *it << " "; ++it; } cout << endl; } void test_list1() { list lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); lt1.push_back(5); lt1.pop_back(); lt1.pop_back(); lt1.pop_back(); print_list(lt1); } void test_list2() { list lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); list lt2(lt1); } void test_list3() { list lt1; //lt1.push_back(1); //lt1.push_back(2); lt1.insert(lt1.begin(), 1); lt1.insert(lt1.begin(), 2); lt1.insert(lt1.begin(), 3); lt1.insert(lt1.begin(), 4); lt1.erase(lt1.begin()); lt1.erase(lt1.begin()); print_list(lt1); } } //reverse_iterator namespace Henry { template class __list_reverse_iterator { public: typedef __list_reverse_iterator self; __list_reverse_iterator(iterator x):_it(x) {} Ref operator*() { iterator prev = _it; return *--prev; } Ptr operator->() { return &operator*(); } self& operator++() { --_it; return *this; } self& operator--() { ++_it; return *this; } bool operator!=(const iterator& rit) const { return rit._it != _it; } private: iterator _it; }; }



