STL容器--list

打印 上一主题 下一主题

主题 992|帖子 992|积分 2976

1. list的介绍及使用
1.1 list的介绍


1. list是可以在常数范围内在任意位置举行插入和删除的序列式容器,并且该容器可从前后双向迭代。
2. list的底层是双向链表结构,双向链表中每个元素存储在互不相干的独立节点中,在节点中通过指针指其前一个元素和后一个元素。
3. list与forward_list非常相似:最紧张的差别在于forward_list是单链表,只能朝前迭代,已让其更简朴高效。
4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置举行插入、移除元素的执行效率更好。
5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,好比:要访问list的第6个元素,必须从已知的位置(好比头部大概尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相干联信息(对于存储类型较小元素的大list来说这大概是一个紧张的因素)
1.2 list的使用

list中的接口比力多,此处类似,只需要把握如何正确的使用,然后再去深入研究背后的原理,已到达可扩展的能力。以下为list中一些常见的紧张接口:
1.2.1 list的构造
 



1.2.2 list iterator的使用

list迭代器可以理解成一个指针,该指针指向list中的某个节点。实际它是指针的封装。

  1. void testlist1()
  2.         {
  3.                 list<int> lt;
  4.                 lt.push_back(1);
  5.                 lt.push_back(2);
  6.                 lt.push_back(3);
  7.                 lt.push_back(4);
  8.                 lt.push_back(5);
  9.                 list<int>::iterator it = lt.begin();
  10.                 cout << *it++ << endl;
  11.                 while (it != lt.end())
  12.                 {
  13.                         cout << *it << " ";
  14.                         it++;
  15.                 }
  16.                 cout << endl;
  17.         }
复制代码

1.2.3 list capacity


1.2.4 list element access


  1. int main()
  2. {
  3.         //list<int> lt(3);
  4.         vector<int> v{ 4,5 };
  5.     vector<string> tokens{ "4","13","5","/","+" };
  6.     cout<<evalRPN(tokens)<<endl;
  7.     list<int> lt;
  8.     lt.push_back(1);
  9.     lt.push_back(2);
  10.     lt.push_back(3);
  11.     lt.push_back(4);
  12.     lt.push_back(5);
  13.     //这里可以直接修改里面第一个元素的值
  14.     lt.front() = 10;  
  15.     for (auto e : lt)
  16.     {
  17.         cout << e << " ";
  18.     }
  19.     cout << endl;
  20.    
  21.         return 0;
  22. }
复制代码
1.2.5 list modifiers


以下代码对部门接口举行测试:
  1.         void testlist3()
  2.         {
  3.                 list<int> lt;
  4.                 lt.push_front(1);
  5.                 lt.push_front(2);
  6.                 lt.push_front(3);
  7.                 lt.push_front(4);
  8.                 lt.push_front(5);
  9.                 for (auto e : lt)
  10.                 {
  11.                         cout << e << " ";
  12.                 }
  13.                 cout << endl;
  14.                 list<int> lt1;
  15.                 lt1.push_front(10);
  16.                 lt1.push_front(20);
  17.                 lt1.push_front(30);
  18.                 lt1.push_front(40);
  19.                 lt.swap(lt1);
  20.                 for (auto e : lt)
  21.                 {
  22.                         cout << e << " ";
  23.                 }
  24.                 cout << endl<<"头删后:"<<endl;
  25.                 lt.erase(lt.begin());
  26.                 for (auto e : lt)
  27.                 {
  28.                         cout << e << " ";
  29.                 }
  30.                 cout << endl;
  31.         }
复制代码


1.2.6 list的迭代器失效

迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中举行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
删除list容器的全部值 正确写法:
  1. void TestListIterator()
  2. {
  3.     int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  4.     list<int> l(array, array + sizeof(array) / sizeof(array[0]));
  5.     for (auto e : l)
  6.     {
  7.         cout << e <<" ";
  8.     }
  9.     auto it = l.begin();
  10.     while (it != l.end())
  11.     {
  12.         //此时it已经指向原来it的下一个迭代器位置
  13.         l.erase(it++); // it = l.erase(it);
  14.         //下面两行为错误写法
  15.         //l.erase(it);
  16.         //++it;
  17.     }
  18.     for (auto e : l)
  19.     {
  20.         cout << e <<endl;
  21.     }
  22. }
复制代码
2. list的模拟实现

2.1 模拟实现list

要模拟实现list,必须要熟悉list的底层结构以及其接口的含义,通过上面的学习,这些内容已基本把握,现在我们来模拟实现list。
  1. namespace xwy {
  2.         template<typename T>
  3.         struct listNode
  4.         {
  5.                 T _data;
  6.                 listNode<T>* _pre;
  7.                 listNode<T>* _next;
  8.                 //单参数构造函数
  9.                 listNode(const T& val = T())
  10.                         :_data(val),
  11.                         _pre(nullptr),
  12.                         _next(nullptr)
  13.                 {
  14.                 }
  15.                
  16.         };
  17.         template<typename T, class Ref, class Ptr>
  18.         struct _list_iterator
  19.         {
  20.                 //  受类域的限制
  21.                 typedef listNode<T> Node;
  22.                 typedef _list_iterator<T,Ref,Ptr> self;
  23.                 Node* _node;
  24.                 _list_iterator(Node *node=nullptr):
  25.                         _node(node)
  26.                 {
  27.                 }
  28.                 //操作符重载
  29.                 Ref operator*()
  30.                 {
  31.                         return _node->_data;
  32.                 }
  33.                 Ptr operator->()
  34.                 {
  35.                         return &(_node->_data);
  36.                 }
  37.                 self& operator--()
  38.                 {
  39.                         _node = _node->_pre;
  40.                         return *this;
  41.                 }
  42.                 self operator-(int a)
  43.                 {
  44.                         Node* ptr = _node;
  45.                         while (a--&&ptr)
  46.                         {
  47.                                 ptr = ptr->_pre;
  48.                         }
  49.                         return ptr;
  50.                 }
  51.                 self& operator++()
  52.                 {
  53.                         _node = _node->_next;
  54.                         return *this;
  55.                 }
  56.                 self operator++(int)
  57.                 {
  58.                         //  self tmp(*this)  拷贝构造自己
  59.                         Node* tmp = _node;
  60.                         _node = _node->_next;
  61.                         return tmp;
  62.                        
  63.                 }
  64.                 bool operator!=(const self& node)const
  65.                 {
  66.                         return _node != node._node;
  67.                 }
  68.         };
  69.         // 适配器 -- 复用
  70.         template<class Iterator, class Ref, class Ptr>
  71.         struct Reverse_iterator
  72.         {
  73.                 Iterator _it;
  74.                 typedef  Reverse_iterator<Iterator, Ref, Ptr> self;
  75.                 Reverse_iterator(const Iterator &it):
  76.                         _it(it)
  77.                 {
  78.                 }
  79.                 //操作符重载
  80.                 Ref operator*()
  81.                 {
  82.                         return *_it;
  83.                 }
  84.                 self& operator--()
  85.                 {
  86.                         ++_it;
  87.                         return *this;
  88.                 }
  89.                 Ptr operator->()
  90.                 {
  91.                         return &(*_it);
  92.                 }
  93.                 self& operator++()
  94.                 {
  95.                         --_it;
  96.                         return *this;
  97.                 }
  98.                 self operator++(int)
  99.                 {
  100.                         //  self tmp(*this)  拷贝构造自己
  101.                         Iterator it = _it;
  102.                         --_it;
  103.                         return it;
  104.                 }
  105.                 bool operator!=(const self& lt) const   //const和const比较 ,非const和const比较
  106.                 {
  107.                         return lt._it != _it;   //不支持那两种类型的比较,是因为不存在那两种类型比较的重载
  108.                 }
  109.         };
  110.         template<typename T>
  111.         class list
  112.         {
  113.         public:
  114.                 typedef listNode<T> Node;
  115.                 typedef _list_iterator<T,T&,T*> iterator;   
  116.                 typedef _list_iterator<T, const T&, const T*> const_iterator;
  117.                 typedef Reverse_iterator<iterator,T&,T*> reverse_iterator;
  118.                 typedef Reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
  119.                 //无参构造函数
  120.                 list()
  121.                 {
  122.                         empty_init();
  123.                        
  124.                 }
  125.                 template<class iterator>
  126.                 list(iterator first,iterator last)
  127.                 {
  128.                         empty_init();
  129.                         while (first != last)
  130.                         {
  131.                                 push_back(*first);
  132.                                 first++;
  133.                         }
  134.                 }
  135.                 //拷贝构造
  136.                 list(const list& lt)
  137.                 {
  138.                         empty_init();
  139.                         auto it = lt.begin();
  140.                         while (it != lt.end())
  141.                         {
  142.                                 push_back(*it);
  143.                                 it++;
  144.                         }
  145.                 }
  146.                 //迭代器的实现
  147.                 iterator begin()
  148.                 {
  149.                         return _head->_next;
  150.                 }
  151.                 iterator end()
  152.                 {
  153.                         return _head;
  154.                 }
  155.                 const_iterator begin() const
  156.                 {
  157.                         return _head->_next;
  158.                 }
  159.                 const_iterator end() const
  160.                 {
  161.                         return _head;
  162.                 }
  163.                 //反向迭代器
  164.                 reverse_iterator rbegin()
  165.                 {
  166.                         return --end();
  167.                 }
  168.                 reverse_iterator rend()
  169.                 {
  170.                         return --begin();
  171.                 }
  172.                 const_reverse_iterator rbegin() const
  173.                 {
  174.                         return --end();
  175.                 }
  176.                 const_reverse_iterator rend() const
  177.                 {
  178.                         return --begin();
  179.                 }
  180.                
  181.                 void push_back(const T& val)
  182.                 {
  183.                         Node* newnode = new Node(val);
  184.                         newnode->_next = _head;
  185.                         _head->_pre->_next = newnode;
  186.                         newnode->_pre = _head->_pre;
  187.                         _head->_pre = newnode;
  188.                 }
  189.                 iterator erase(iterator pos) //在pos位置删除
  190.                 {
  191.                         Node* cur = pos._node;
  192.                         Node* prev = cur->_pre;
  193.                         Node* next = cur->_next;
  194.                         delete cur;
  195.                         prev->_next = next;
  196.                         next->_pre = prev;
  197.                
  198.                         return next;
  199.                 }
  200.                 // 在pos位置前插入值为val的节点
  201.                 iterator insert(iterator pos, const T& val)
  202.                 {
  203.                         Node* cur = pos._node;
  204.                         Node* newNode = new Node(val);
  205.                         newNode->_next = cur;
  206.                         newNode->_pre = cur->_pre;
  207.                         cur->_pre->_next = newNode;
  208.                         cur->_pre = newNode;
  209.                         return pos;
  210.                 }
  211.                 /*void push_back(const T& val)
  212.                 {
  213.                         insert(_head, val);
  214.                 }*/
  215.                 void push_front(const T& val)
  216.                 {
  217.                         insert(_head->_next, val);
  218.                 }
  219.                 void swap(list<T>& l)
  220.                 {
  221.                         std::swap(l._head, _head);
  222.                 }
  223.        
  224.                 void clear()
  225.                 {
  226.                         //清理数据,不清头节点
  227.                         iterator it = begin();
  228.                         while (it != end())
  229.                         {
  230.                                 it = erase(it);//it就是下一个位置
  231.                         }
  232.                 }
  233.                 ~list()
  234.                 {
  235.                         clear();
  236.                         delete _head;                // 只有节点是new出来,需要delete,但这个只delete 了一个节点
  237.                 }
  238.         private:
  239.                 void empty_init()
  240.                 {
  241.                         _head = new Node();
  242.                         _head->_next = _head->_pre = _head;
  243.                 }
  244.                 Node* _head;  
  245.         };
复制代码
2.2 list的反向迭代器

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

vector与list都是STL中非常紧张的序列式容器,由于两个容器的底层结构差别,导致其特性以及应用场景差别,其紧张差别如下:


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

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

吴旭华

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表