hello,各位小伙伴,本篇文章跟大家一起学习《C++:list模拟实现》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !
如果本篇文章对你有帮助,还请各位点点赞!!!
话不多说,开始进入正题
是一个双指针带头链表,所以我选择用一个结构体ListNode
来维护节点,如下:
// List的节点类 template struct ListNode { ListNode(const T& val = T()) :_val(val) ,_pPre(nullptr) ,_pNext(nullptr) {} ListNode* _pPre;// 指向前一个结点 ListNode* _pNext;// 指向后一个节点 T _val;// 该结点的值 };
我对ListNode
改一个名字:Node
:
typedef ListNode Node; typedef Node* PNode;
_pHead
和私有成员函数CreateHead()
private: void CreateHead()// 创建头节点并且初始化 { _pHead = new Node(); _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; } PNode _pHead;
尾插只是插入的其中一种方式,所以实现了插入函数,就能够实现尾插函数。
插入思路图解:在pos位置前插入值为val的节点
创建新节点值为value后; 使prev节点的_pNext指针指向newnode,newnode的节点的_pPre指向prev; 使cur节点的_pPre指针指向newnode,newnode的节点的_pNext指向cur; 最后返回iterator(newnode);
itearator
为迭代器,后面会实现
// 在pos位置前插入值为val的节点 iterator insert(iterator pos, const T& val) { Node* cur = pos._pNode; Node* newnode = new Node(val); Node* prev = cur->_pPre; // prev newnode cur prev->_pNext = newnode; newnode->_pPre = prev; newnode->_pNext = cur; cur->_pPre = newnode; return iterator(newnode); }
void push_back(const T& val) { insert(end(), val); }
list(const PNode& pHead = nullptr) { CreateHead(); /*_pHead = new Node(); _pHead->_pNext = _pHead; _pHead->_pPre = _pHead;*/ }
list(int n, const T& value = T()) { CreateHead(); for (int i = 0; i < n; ++i) push_back(value); }
template list(Iterator first, Iterator last) { CreateHead(); while (first != last) { push_back(*first); ++first; } }
list(const list& l) { CreateHead(); // 复用带参构造(迭代器) list temp(l.cbegin(), l.cend()); // 与*this的头节点pHead交换指向 swap(temp); }
clear()
为其中的成员函数,功能:清理list
中的数据
~list() { clear(); delete _pHead; _pHead = nullptr; /*Node* cur = _pHead->_pNext; Node* tmp = cur->_pNext; while (cur != _pHead) { delete cur; cur = tmp; tmp = tmp->_pNext; } tmp = cur = nullptr; _pHead->_pNext = _pHead; _pHead->_pPre = _pHead;*/ }
逻辑上并不难,也许难理解于模板
//List的迭代器结构体 template struct ListIterator { typedef ListNode* PNode; typedef ListIterator Self; ListIterator(PNode pNode = nullptr) :_pNode(pNode) {} ListIterator(const Self& l) { _pNode = l._pNode; } T& operator*() { assert(_pNode != _pNode->_pNext); return _pNode->_val; } T* operator->() { return &(*this); } Self& operator++() { _pNode = _pNode->_pNext; return *this; } Self operator++(int) { PNode* tmp = _pNode; _pNode = _pNode->_pNext; return tmp; } Self& operator--() { _pNode = _pNode->_pPre; return *this; } Self& operator--(int) { PNode* tmp = _pNode; _pNode = _pNode->_pPre; return tmp; } bool operator!=(const Self& l) { return _pNode != l._pNode; } bool operator==(const Self& l) { return !(*this != l); } PNode _pNode; };
这段代码定义了一个模板结构 ListIterator
,用于表示List
类的迭代器。让我们来解释模板声明部分:
template;
这一行是模板声明,定义了一个模板类 ListIterator
,它有三个模板参数:T、Ref 和 Ptr
。让我们逐个解释这些参数的作用:
1.T
: 这是一个模板参数,表示迭代器指向的元素类型。在使用 ListIterator 时,你需要提供实际的类型作为 T 的值。
2.Ref
: 这也是一个模板参数,表示迭代器的引用类型。通常情况下,当你通过迭代器解引用(使用 * 运算符)时,你希望得到的是元素的引用类型。所以 Ref 通常被设定为 T&,表示引用类型为 T 的元素。
3.Ptr
: 这是迭代器的指针类型。与 Ref 类似,当你通过迭代器解引用(使用 -> 运算符)时,你希望得到的是元素的指针类型。因此,通常情况下 Ptr 被设定为 T*,表示指针类型为 T 的元素。
通过将这些参数设定为模板参数,ListIterator
类可以适用于不同类型的元素,同时也可以提供不同的引用和指针类型。这样做使得 ListIterator
类更加灵活,能够适用于不同的使用场景。
总的来说,将迭代器封装为独立的类使得代码更加模块化、可重用、灵活和通用,提高了代码的可维护性、可扩展性和可读性。
list
类中迭代器的使用public: typedef ListIterator iterator; typedef ListIterator const_iterator;
// List Iterator iterator begin() { return _pHead->_pNext; } iterator end() { return _pHead; } const_iterator begin() const { return _pHead->_pNext; } const_iterator end() const { return _pHead; }
iterator erase(iterator pos) { assert(pos._pNode != _pHead); Node* Prev = pos._pNode->_pPre; Node* Next = pos._pNode->_pNext; delete pos._pNode; Prev->_pNext = Next; Next->_pPre = Prev; return iterator(Next); }
void push_back(const T& val) { insert(end(), val); } void pop_back() { erase(--end()); } void push_front(const T& val) { assert(!empty()); insert(begin(), val); } void pop_front() { erase(begin()); }
#pragma once #include #include using namespace std; namespace My_List { // List的节点类 template struct ListNode { ListNode(const T& val = T()) :_val(val) ,_pPre(nullptr) ,_pNext(nullptr) {} ListNode* _pPre; ListNode* _pNext; T _val; }; //List的迭代器类 template struct ListIterator { typedef ListNode* PNode; typedef ListIterator Self; ListIterator(PNode pNode = nullptr) :_pNode(pNode) {} ListIterator(const Self& l) { _pNode = l._pNode; } T& operator*() { assert(_pNode != _pNode->_pNext); return _pNode->_val; } T* operator->() { return &(*this); } Self& operator++() { _pNode = _pNode->_pNext; return *this; } Self operator++(int) { PNode* tmp = _pNode; _pNode = _pNode->_pNext; return tmp; } Self& operator--() { _pNode = _pNode->_pPre; return *this; } Self& operator--(int) { PNode* tmp = _pNode; _pNode = _pNode->_pPre; return tmp; } bool operator!=(const Self& l) { return _pNode != l._pNode; } bool operator==(const Self& l) { return !(*this != l); } PNode _pNode; }; //list类 template class list { typedef ListNode Node; typedef Node* PNode; public: typedef ListIterator iterator; typedef ListIterator const_iterator; public: /// // List的构造 list(const PNode& pHead = nullptr) { CreateHead(); /*_pHead = new Node(); _pHead->_pNext = _pHead; _pHead->_pPre = _pHead;*/ } list(int n, const T& value = T()) { CreateHead(); for (int i = 0; i < n; ++i) push_back(value); /*int cnt = 0; while (cnt < n) { PNode _first = new Node(value); PNode tmp = _pHead->_pPre; tmp->_pNext = _first; _first->_pPre = tmp; _first->_pNext = _pHead; _pHead->_pPre = _first; ++cnt; }*/ } template list(Iterator first, Iterator last) { CreateHead(); while (first != last) { push_back(*first); ++first; } /*while (first != last) { PNode _first = new Node(*first); PNode tmp = _pHead->_pPre; tmp->_pNext = _first; _first->_pPre = tmp; _first->_pNext = _pHead; _pHead->_pPre = _first; ++first; }*/ } list(const list& l) { CreateHead(); list temp(l.cbegin(), l.cend()); swap(temp); /*iterator first = l._pHead->_pNext; iterator last = l._pHead; while (first != last) { PNode _first = new Node(*first); PNode tmp = _pHead->_pPre; tmp->_pNext = _first; _first->_pPre = tmp; _first->_pNext = _pHead; _pHead->_pPre = _first; ++first; }*/ } list& operator=(const list l) { CreateHead(); swap(l); return *this; /*iterator first = l._pHead->_pNext; iterator last = l._pHead; while (first != last) { PNode _first = new Node(*first); PNode tmp = _pHead->_pPre; tmp->_pNext = _first; _first->_pPre = tmp; _first->_pNext = _pHead; _pHead->_pPre = _first; ++first; } return *this;*/ } ~list() { clear(); delete _pHead; _pHead = nullptr; /*Node* cur = _pHead->_pNext; Node* tmp = cur->_pNext; while (cur != _pHead) { delete cur; cur = tmp; tmp = tmp->_pNext; } tmp = cur = nullptr; _pHead->_pNext = _pHead; _pHead->_pPre = _pHead;*/ } /// // List Iterator iterator begin() { return _pHead->_pNext; } iterator end() { return _pHead; } const_iterator begin() const { return _pHead->_pNext; } const_iterator end() const { return _pHead; } /// // List Capacity size_t size()const { Node* cur = _pHead->_pNext; size_t cnt = 0; while (cur != _pHead) { ++cnt; cur = cur->_pNext; } return cnt; } bool empty()const { return size() == 0; } // List Access T& front() { return _pHead->_pNext->_val; } const T& front()const { return _pHead->_pNext->_val; } T& back() { return _pHead->_pPre->_val; } const T& back()const { return _pHead->_pPre->_val; } // List Modify void push_back(const T& val) { insert(end(), val); } void pop_back() { erase(--end()); } void push_front(const T& val) { assert(!empty()); insert(begin(), val); } void pop_front() { erase(begin()); } // 在pos位置前插入值为val的节点 iterator insert(iterator pos, const T& val) { Node* cur = pos._pNode; Node* newnode = new Node(val); Node* prev = cur->_pPre; // prev newnode cur prev->_pNext = newnode; newnode->_pPre = prev; newnode->_pNext = cur; cur->_pPre = newnode; return iterator(newnode); } // 删除pos位置的节点,返回该节点的下一个位置 iterator erase(iterator pos) { assert(pos._pNode != _pHead); Node* Prev = pos._pNode->_pPre; Node* Next = pos._pNode->_pNext; delete pos._pNode; Prev->_pNext = Next; Next->_pPre = Prev; return iterator(Next); } void clear() { iterator cur = begin(); while (cur != end()) { cur = erase(cur); } _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; } void swap(list& l) { /*list tmp = l; l = *this; *this = tmp;*/ PNode tmp = _pHead; _pHead = l._pHead; l._pHead = tmp; } private: void CreateHead() { _pHead = new Node(); _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; } PNode _pHead; }; };
你学会了吗?
好啦,本章对于《C++:list模拟实现》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!
如你喜欢,点点赞就是对我的支持,感谢感谢!!!