ToB企服应用市场:ToB评测及商务社交产业平台

标题: C++第十二弹 -- STL之list模拟实现 [打印本页]

作者: 去皮卡多    时间: 2024-8-26 11:35
标题: C++第十二弹 -- STL之list模拟实现
前言

通过模拟实现可以让我们更加深刻的理解C++底层STL的实现逻辑, 本篇就对list的底层进行模拟实现.
博客主页: 酷酷学!!! 点击关注 共同进步!!!

正文开始
模拟实现list

要模拟实现list, 必须要熟悉list的底层结构以及其接口的寄义, 通过上一篇的学习, 这些内容基本把握之后, 如今我们来模拟实现list.
1. ListNode节点类

  1. #pragma once
  2. #include<iostream>
  3. using namespace std;
  4. #include<assert.h>
  5. namespace my
  6. {
  7.         //list的节点类
  8.         template<class T>
  9.         struct ListNode
  10.         {
  11.                 ListNode(const T& val = T())
  12.                         : _prev(nullptr)
  13.                         , _next(nullptr)
  14.                         , _val(val)
  15.                 {}
  16.                 ListNode<T>* _prev;
  17.                 ListNode<T>* _next;
  18.                 T _val;
  19.         };
复制代码
2. list的迭代器封装

  1. list的迭代器
  2. 迭代器有两种实现方式, 具体应根据容器底层数据结构的实现:
  3. 1.原生态指针, 比如:vector
  4. 2.将原生态指针进行封装, 因迭代器使用形式与指针完全相同,
  5. 因此在自定义的类中必须实现以下方法:
  6.         1.指针可以解引用,迭代器的类中必须重载operator*()
  7.         2.指针可以通过->访问其所指空间成员,迭代器类中必须重载operator->()
  8.         3.指针可以++向后移动,迭代器类中必须重载operator++()与operator++(int)
  9.           至于operator--()/operator--(int)释放需要重载,根据具体的结构来抉择,
  10.           双向链表可以向前或者向后移动,所以需要重载,如果是forward_list就不需要重载--
  11.         4.迭代器需要进行是否相等的比较,因此还需要重载operator==()与operator!=()
复制代码
  1.         template<class T,class Ref,class Ptr>
  2.         class ListIterator
  3.         {
  4.                 typedef ListNode<T> Node;
  5.                 typedef ListIterator<T, Ref, Ptr> Self;
  6.                 //Ref 和 Ptr类型需要重新定义下,实现反向迭代器时需要用到
  7.         public:
  8.                 typedef Ref Ref;
  9.                 typedef Ptr Ptr;
  10.                 //构造
  11.                 ListIterator(Node* node = nullptr)
  12.                         : _node(node)
  13.                 {}
  14.                 //具有指针类似行为
  15.                 Ref operator*()
  16.                 {
  17.                         return _node->_val;
  18.                 }
  19.                 Ptr operator->()
  20.                 {
  21.                         return &(operator*());
  22.                 }
  23.                 //迭代器支持移动
  24.                 Self& operator++()
  25.                 {
  26.                         _node = _node->_next;
  27.                         return *this;
  28.                 }
  29.                 Self operator++(int)
  30.                 {
  31.                         Self temp(*this);
  32.                         _node = _node->_next;
  33.                         return temp;
  34.                 }
  35.                 Self& operator--()
  36.                 {
  37.                         _node = _node->_prev;
  38.                         return *this;
  39.                 }
  40.                 Self operator--(int)
  41.                 {
  42.                         Self temp(*this);
  43.                         _node = _node->_prev;
  44.                         return temp;
  45.                 }
  46.                 //迭代器支持比较
  47.                 bool operator!=(const Self& l) const
  48.                 {
  49.                         return _node != l._node;
  50.                 }
  51.                 bool operator==(const Self & l) const
  52.                 {
  53.                         return _node == l._node;
  54.                 }
  55.                 Node* _node;
  56.         };
复制代码
3. 反向迭代器

  1.         //反向迭代器,迭代器复用
  2.         template<class Iterator>
  3.         class ReverseListIterator
  4.         {
  5.                 //注意:此处typename的作用是明确的告诉编译器,Ref是Iterator类中的一个类型,
  6.                 //而不是静态成员变量,否则编译器编译时就不知道Ref是Iterator中的类型还是静态成员
  7.                 //变量,因为静态成员变量也是按照 类名::静态成员变量名 的方式访问的
  8.         public:
  9.                 typedef typename Iterator::Ref Ref;
  10.                 typedef typename Iterator::Ptr Ptr;
  11.                 typedef ReverseListIterator<Iterator> Self;
  12.                 //构造
  13.                 ReverseListIterator(Iterator it)
  14.                         : _it(it)
  15.                 {}
  16.                 //具有指针类似行为
  17.                 Ref operator*()
  18.                 {
  19.                         Iterator temp(_it);
  20.                         --temp;
  21.                         return *temp;
  22.                 }
  23.                 Ptr operator->()
  24.                 {
  25.                         return &(operator*());
  26.                 }
  27.                 //迭代器支持移动
  28.                 Self& operator++()
  29.                 {
  30.                         --_it;
  31.                         return *this;
  32.                 }
  33.                 Self& operator++(int)
  34.                 {
  35.                         Self temp(*this);
  36.                         --_it;
  37.                         return *this;
  38.                 }
  39.                 Self& operator--()
  40.                 {
  41.                         ++_it;
  42.                         return *this;
  43.                 }
  44.                 Self& operator--(int)
  45.                 {
  46.                         Self temp(*this);
  47.                         ++_it;
  48.                         return temp;
  49.                 }
  50.                 //迭代器支持比较
  51.                 bool operator!=(const Self& l) const
  52.                 {
  53.                         return _it != l._it;
  54.                 }
  55.                 bool operator==(const Self& l) const
  56.                 {
  57.                         return _it == l._it;
  58.                 }
  59.                 Iterator _it;
  60.         };
复制代码
4. list类的模拟实现

  1.         template<class T>
  2.         class list
  3.         {
  4.                 typedef ListNode<T> Node;
  5.         public:
  6.                 //正向迭代器
  7.                 typedef ListIterator<T, T&, T*> iterator;
  8.                 typedef ListIterator<T, const T&, T*> const_iterator;
  9.                 //反向迭代器
  10.                 typedef ReverseListIterator<iterator> reverse_iterator;
  11.                 typedef ReverseListIterator<const_iterator> const_reverse_iterator;
  12.                
  13.                 //List的构造
  14.                 list()
  15.                 {
  16.                         CreateHead();
  17.                 }
  18.                 list(int n, const T& value = T())
  19.                 {
  20.                         CreateHead();
  21.                         for (int i = 0; i < n; ++i)
  22.                         {
  23.                                 push_back(value);
  24.                         }
  25.                 }
  26.                 template<class Iterator>
  27.                 list(Iterator first, Iterator last)
  28.                 {
  29.                         CreateHead();
  30.                         while (first != last)
  31.                         {
  32.                                 push_back(*first);
  33.                                 ++first;
  34.                         }
  35.                 }
  36.                
  37.                 list(const list<T>& l)
  38.                 {
  39.                         CreateHead();
  40.                         //用l中的元素构造临时的temp,然后与当前对象交换
  41.                         list<T> temp(l.begin(), l.end());
  42.                         this->swap(temp);
  43.                 }
  44.                 list<T>& operator=(list<T> l)
  45.                 {
  46.                         this->swap(l);
  47.                         return *this;
  48.                 }
  49.                 ~list()
  50.                 {
  51.                         clear();
  52.                         delete _head;
  53.                         _head = nullptr;
  54.                 }
  55.                 //list的迭代器
  56.                 iterator begin()
  57.                 {
  58.                         return iterator(_head->_next);
  59.                 }
  60.                 iterator end()
  61.                 {
  62.                         return iterator(_head);
  63.                 }
  64.                 const_iterator begin() const
  65.                 {
  66.                         return const_iterator(_head->_next);
  67.                 }
  68.                 const_iterator end() const
  69.                 {
  70.                         return const_iterator(_head);
  71.                 }
  72.                 reverse_iterator rbegin()
  73.                 {
  74.                         return reverse_iterator(end());
  75.                 }
  76.                 reverse_iterator rend()
  77.                 {
  78.                         return reverse_iterator(begin());
  79.                 }
  80.                 const_reverse_iterator rbegin() const
  81.                 {
  82.                         return const_reverse_iterator(end());
  83.                 }
  84.                 const_reverse_iterator rend() const
  85.                 {
  86.                         return const_reverse_iterator(begin());
  87.                 }
  88.                 //List的容器相关
  89.                 size_t size() const
  90.                 {
  91.                         Node* cur = _head->_next;
  92.                         size_t count = 0;
  93.                         while (cur != _head)
  94.                         {
  95.                                 ++count;
  96.                                 cur = cur->_next;
  97.                         }
  98.                         return count;
  99.                 }
  100.                 bool empty() const
  101.                 {
  102.                         return _head->_next = _head;
  103.                 }
  104.                 void resize(size_t newsize, const T* data = T())
  105.                 {
  106.                         size_t oldsize = size();
  107.                         if (newsize <= oldsize)
  108.                         {
  109.                                 //将有效元素减少到newsize
  110.                                 while (newsize < oldsize)
  111.                                 {
  112.                                         pop_back();
  113.                                         --oldsize;
  114.                                 }
  115.                         }
  116.                         else
  117.                         {
  118.                                 while (oldsize < newsize)
  119.                                 {
  120.                                         push_back(data);
  121.                                         ++oldsize;
  122.                                 }
  123.                         }
  124.                 }
  125.                 //list的元素访问操作
  126.                 //注意:List不支持operator[]
  127.                 T& front()
  128.                 {
  129.                         return _head->_next->_val;
  130.                 }
  131.                 const T& front() const
  132.                 {
  133.                         return _head->_next->_val;
  134.                 }
  135.                 T& back()
  136.                 {
  137.                         return _head->_prev->_val;
  138.                 }
  139.                 const T& back() const
  140.                 {
  141.                         return _head->_prev->_val;
  142.                 }
  143.                 //list的插入和删除
  144.                 void push_back(const T& val)
  145.                 {
  146.                         insert(end(), val);
  147.                 }
  148.                 void pop_back()
  149.                 {
  150.                         erase(--end());
  151.                 }
  152.                 void push_front(const T& val)
  153.                 {
  154.                         insert(begin(), val);
  155.                 }
  156.                 void pop_front()
  157.                 {
  158.                         erase(begin());
  159.                 }
  160.                 //在pos位置前插入值为val的节点
  161.                 iterator insert(iterator pos, const T& val)
  162.                 {
  163.                         Node* pNewNode = new Node(val);
  164.                         Node* pCur = pos._node;
  165.                         //先将新节点插入
  166.                         pNewNode->_prev = pCur->_prev;
  167.                         pNewNode->_next = pCur;
  168.                         pNewNode->_prev->_next = pNewNode;
  169.                         pCur->_prev = pNewNode;
  170.                         return iterator(pNewNode);
  171.                 }
  172.                 //删除pos位置的节点,返回该节点的下一个位置
  173.                 iterator erase(iterator pos)
  174.                 {
  175.                         //找到待删除的节点
  176.                         Node* pDel = pos._node;
  177.                         Node* pRet = pDel->_next;
  178.                         //将该节点从链表中拆下来并删除
  179.                         pDel->_prev->_next = pDel->_next;
  180.                         pDel->_next->_prev = pDel->_prev;
  181.                         delete pDel;
  182.                         return iterator(pRet);
  183.                 }
  184.                 void clear()
  185.                 {
  186.                         Node* cur = _head->_next;
  187.                         //采用头删除删除
  188.                         while (cur != _head)
  189.                         {
  190.                                 Node* next = cur->_next;
  191.                                 delete cur;
  192.                                 cur = next;
  193.                         }
  194.                         _head->_next = _head->_prev = _head;
  195.                 }
  196.                
  197.                 void swap(my::list<T>& l)
  198.                 {
  199.                         std::swap(_head, l._head);
  200.                 }
  201.         private:
  202.                 void CreateHead()
  203.                 {
  204.                         _head = new Node;
  205.                         _head->_prev = _head;
  206.                         _head->_next = _head;
  207.                 }
  208.                 Node* _head;
  209.         };       
  210. }
复制代码
测试代码

对构造函数进行测试
  1. //对模拟实现的list进行测试
  2. //正向打印链表
  3. template<class T>
  4. void PrintList(const my::list<T>& l)
  5. {
  6.         auto it = l.begin();
  7.         while (it != l.end())
  8.         {
  9.                 cout << *it << " ";
  10.                 ++it;
  11.         }
  12.         cout << endl;
  13. }
  14. //测试list的构造
  15. void Testmylist1()
  16. {
  17.         my::list<int> l1;
  18.         my::list<int> l2(10, 5);
  19.         PrintList(l2);
  20.         int array[] = { 1,2,3,4,5,6,7,8,9,0 };
  21.         my::list<int> l3(array, array + sizeof(array) / sizeof(array[0]));
  22.         PrintList(l3);
  23.         my::list<int> l4(l3);
  24.         PrintList(l4);
  25.         l1 = l4;
  26.         PrintList(l1);
  27. }
复制代码

对头/尾插入删除进行测试
  1. //PushBack()/PopBack()/PushFront()/PopFront()
  2. void Testmylist2()
  3. {
  4.         //测试pushBack和PopBack
  5.         my::list<int> l;
  6.         l.push_back(1);
  7.         l.push_back(2);
  8.         l.push_back(3);
  9.         PrintList(l);
  10.         l.pop_back();
  11.         l.pop_back();
  12.         PrintList(l);
  13.         l.pop_back();
  14.         cout << l.size() << endl;
  15.         //测试pushFront与popFront
  16.         l.push_front(1);
  17.         l.push_front(2);
  18.         l.push_front(3);
  19.         PrintList(l);
  20.         l.pop_front();
  21.         l.pop_front();
  22.         PrintList(l);
  23.         l.pop_front();
  24.         cout << l.size() << endl;
  25. }
复制代码

测试指定位置插入删除
  1. //测试insert和erase
  2. void Testmylist3()
  3. {
  4.         int array[] = { 1,2,3,4,5 };
  5.         my::list<int> l(array, array + sizeof(array) / sizeof(array[0]));
  6.         auto pos = l.begin();
  7.         l.insert(l.begin(), 0);
  8.         PrintList(l);
  9.         ++pos;
  10.         l.insert(pos, 2);
  11.         PrintList(l);
  12.         l.erase(l.begin());
  13.         l.erase(pos);
  14.         PrintList(l);
  15.         //pos指向的节点已经被删除,pos迭代器失效
  16.         cout << *pos << endl;
  17.         auto it = l.begin();
  18.         while (it != l.end())
  19.         {
  20.                 it = l.erase(it);
  21.         }
  22.         cout << l.size() << endl;
  23. }
复制代码

测试反向迭代器
  1. //测试反向迭代器
  2. void Testmylist4()
  3. {
  4.         int array[] = { 1,2,3,4,5 };
  5.         my::list<int> l(array, array + sizeof(array) / sizeof(array[0]));
  6.        
  7.         auto rit = l.rbegin();
  8.         while (rit != l.rend())
  9.         {
  10.                 cout << *rit << " ";
  11.                 ++rit;
  12.         }
  13.         cout << endl;
  14.         const my::list<int> cl(l);
  15.         auto crit = l.rbegin();
  16.         while (crit != l.rend())
  17.         {
  18.                 cout << *crit <<" ";
  19.                 ++crit;
  20.         }
  21.         cout << endl;
  22. }
复制代码

list的反向迭代器

我们知道, 反向迭代器的++就是正向迭代器的- -, 反向迭代器的- -就是正向迭代器的++, 因此反向迭代器的实现可以借助正向迭代器, 即: 返现迭代器内部可以包含一个正向迭代器, 对正向迭代器的接口进行包装即可.
  1.         //反向迭代器,迭代器复用
  2.         template<class Iterator>
  3.         class ReverseListIterator
  4.         {
  5.                 //注意:此处typename的作用是明确的告诉编译器,Ref是Iterator类中的一个类型,
  6.                 //而不是静态成员变量,否则编译器编译时就不知道Ref是Iterator中的类型还是静态成员
  7.                 //变量,因为静态成员变量也是按照 类名::静态成员变量名 的方式访问的
  8.         public:
  9.                 typedef typename Iterator::Ref Ref;
  10.                 typedef typename Iterator::Ptr Ptr;
  11.                 typedef ReverseListIterator<Iterator> Self;
  12.                 //构造
  13.                 ReverseListIterator(Iterator it)
  14.                         : _it(it)
  15.                 {}
  16.                 //具有指针类似行为
  17.                 Ref operator*()
  18.                 {
  19.                         Iterator temp(_it);
  20.                         --temp;
  21.                         return *temp;
  22.                 }
  23.                 Ptr operator->()
  24.                 {
  25.                         return &(operator*());
  26.                 }
  27.                 //迭代器支持移动
  28.                 Self& operator++()
  29.                 {
  30.                         --_it;
  31.                         return *this;
  32.                 }
  33.                 Self& operator++(int)
  34.                 {
  35.                         Self temp(*this);
  36.                         --_it;
  37.                         return *this;
  38.                 }
  39.                 Self& operator--()
  40.                 {
  41.                         ++_it;
  42.                         return *this;
  43.                 }
  44.                 Self& operator--(int)
  45.                 {
  46.                         Self temp(*this);
  47.                         ++_it;
  48.                         return temp;
  49.                 }
  50.                 //迭代器支持比较
  51.                 bool operator!=(const Self& l) const
  52.                 {
  53.                         return _it != l._it;
  54.                 }
  55.                 bool operator==(const Self& l) const
  56.                 {
  57.                         return _it == l._it;
  58.                 }
  59.                 Iterator _it;
  60.         };
复制代码


总结

通过以上的实现,可以模拟出一个雷同于list的数据结构,而且可以对其中的元素进行添加、删除、查找、等利用。如许就可以在不使用C++内置的list时,使用自己实现的List类来进行相同的利用。
感谢您的点赞与收藏!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4