list(c++)

打印 上一主题 下一主题

主题 1642|帖子 1642|积分 4926

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
list介绍

list是STL容器中的容器,且元素在容器中的位置是分散的并与巨细无关。list的底层是双向链表,其优势是在恣意位置插入和删除元素的时间复杂度为O(1),但无法通过“下标[ ]”直接访问元素,需要通过从头(尾)遍历元素找到元素,多用于需要大量数据的插入和删除,且对数据的随机访问比较少。

list利用

一、list的构造

构造函数接口分析           list (size_type n, const value_type& val =       value_type())                  构造的      list      中包罗      n      个值为      val            元素                 list()                 构造空的      list                 list (const list& x)                 拷贝构造函数                 list (InputIterator first, InputIterator last)                       [first, last)      区间中的元素构造      list        
  1. // list的构造
  2.     list<int> l1;                         // 构造空的l1
  3.     list<int> l2(4, 100);                 // l2中放4个值为100的元素
  4.     list<int> l3(l2.begin(), l2.end());  // 用l2的[begin(), end())左闭右开的区间构造l3
  5.     list<int> l4(l3);                    // 用l3拷贝构造l4
  6.     // 以数组为迭代器区间构造l5
  7.     int array[] = { 16,2,77,29 };
  8.     list<int> l5(array, array + sizeof(array) / sizeof(int));
  9.     // 列表格式初始化C++11
  10.     list<int> l6{ 1,2,3,4,5 };
复制代码
二、list 的iterator的利用

 
接口分析           begin       +       end                  返回第一个元素的迭代器      +      返回最后一个元素下一个位置的迭代器                 rbegin                 +       rend                 返回第一个元素的      reverse_iterator,            end      位置      ,      返回最后一个元素下一个位      置的      reverse_iterator,            begin      位置        
  1. // list迭代器的使用
  2. // 注意:遍历链表只能用迭代器和范围for
  3. void PrintList(const list<int>& l)
  4. {
  5.     // 注意这里调用的是list的 begin() const,返回list的const_iterator对象
  6.     for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it)
  7.     {
  8.         cout << *it << " ";
  9.         // *it = 10; 编译不通过
  10.     }
  11.     cout << endl;
  12. }
  13. void TestList2()
  14. {
  15.     int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  16.     list<int> l(array, array + sizeof(array) / sizeof(array[0]));
  17.     // 使用正向迭代器正向list中的元素
  18.     // list<int>::iterator it = l.begin();   // C++98中语法
  19.     auto it = l.begin();                     // C++11之后推荐写法
  20.     while (it != l.end())
  21.     {
  22.         cout << *it << " ";
  23.         ++it;
  24.     }
  25.     cout << endl;
  26.     // 使用反向迭代器逆向打印list中的元素
  27.     // list<int>::reverse_iterator rit = l.rbegin();
  28.     auto rit = l.rbegin();
  29.     while (rit != l.rend())
  30.     {
  31.         cout << *rit << " ";
  32.         ++rit;
  33.     }
  34.     cout << endl;
  35. }
复制代码
三、list capacity

接口分析empty           检测      list      是否为空,是返回      true      ,否则返回      false      size           返回      list      中有用节点的个数        四、list element access

接口分析front           返回      list      的第一个节点中值的引用      back           返回      list      的最后一个节点中值的引用       五、list modifiers 

接口分析push_front                 list      首元素前插入值为      val      的元素      pop_front           删除      list      中第一个元素      push_back                 list      尾部插入值为      val      的元素      pop_back           删除      list      中最后一个元素      insert                 list position       位置中插入值为      val      的元素      erase           删除      list position      位置的元素      swap           互换两个      list      中的元素      clear           清空      list      中的有用元素      
  1. // list插入和删除
  2. // push_back/pop_back/push_front/pop_front
  3. void TestList3()
  4. {
  5.     int array[] = { 1, 2, 3 };
  6.     list<int> L(array, array + sizeof(array) / sizeof(array[0]));
  7.     // 在list的尾部插入4,头部插入0
  8.     L.push_back(4);
  9.     L.push_front(0);
  10.     PrintList(L);
  11.     // 删除list尾部节点和头部节点
  12.     L.pop_back();
  13.     L.pop_front();
  14.     PrintList(L);
  15. }
  16. // insert /erase
  17. void TestList4()
  18. {
  19.     int array1[] = { 1, 2, 3 };
  20.     list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));
  21.     // 获取链表中第二个节点
  22.     auto pos = ++L.begin();
  23.     cout << *pos << endl;
  24.     // 在pos前插入值为4的元素
  25.     L.insert(pos, 4);
  26.     PrintList(L);
  27.     // 在pos前插入5个值为5的元素
  28.     L.insert(pos, 5, 5);
  29.     PrintList(L);
  30.     // 在pos前插入[v.begin(), v.end)区间中的元素
  31.     vector<int> v{ 7, 8, 9 };
  32.     L.insert(pos, v.begin(), v.end());
  33.     PrintList(L);
  34.     // 删除pos位置上的元素
  35.     L.erase(pos);
  36.     PrintList(L);
  37.     // 删除list中[begin, end)区间中的元素,即删除list中的所有元素
  38.     L.erase(L.begin(), L.end());
  39.     PrintList(L);
  40. // 交换l1和l2中的元素
  41.     list<int> l2;
  42.     l1.swap(l2);
  43.     PrintList(l1);
  44.     PrintList(l2);
  45.     // 将l2中的元素清空
  46.     l2.clear();
  47.     cout << l2.size() << endl;
  48. }
复制代码
 六、list的迭代器失效

      可将迭代器临时理解成雷同于指针,迭代器失效即迭代器所指向的节点的无   效,即该节点被删除了。由于list的底层布局为带头结点的双向循环链表,因此在list中举行插入   时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭   代器,其他迭代器不会受到影响。   
  1. void TestListIterator1()
  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.     auto it = l.begin();
  6.     while (it != l.end())
  7.       {
  8.       // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给
  9.         其赋值
  10.         l.erase(it);
  11.         ++it;
  12.       }
  13. }
  14. // 改正
  15. void TestListIterator()
  16. {
  17.     int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  18.     list<int> l(array, array+sizeof(array)/sizeof(array[0]));
  19.     auto it = l.begin();
  20.     while (it != l.end())
  21.     {
  22.         l.erase(it++); // it = l.erase(it);
  23.     }
  24. }
复制代码
 
模拟实现

一、节点

  1. template<class T>
  2.         struct list_node
  3.         {
  4.                 T _data;
  5.                 list_node<T>* _next;
  6.                 list_node<T>* _prev;
  7.                 list_node(const T& x = T())
  8.                         :_data(x)
  9.                         , _next(nullptr)
  10.                         , _prev(nullptr)
  11.                 {}
  12.         };
复制代码
二、构造

  1.         void empty_init()
  2.                 {
  3.                         _head = new Node();
  4.                         _head->_next = _head;
  5.                         _head->_prev = _head;
  6.                         _size = 0;
  7.                 }
  8.        //无参构造
  9.                 list()
  10.                 {
  11.                         empty_init();
  12.                 }
  13.         //拷贝构造
  14.                 // lt2(lt1)
  15.                 list(const list<T>& lt)
  16.                 {
  17.                         empty_init();
  18.                         for (auto& e : lt)
  19.                         {
  20.                                 push_back(e);
  21.                         }
  22.                 }
  23.         //n个val构造
  24.         list(size_t n, const T& val = T())
  25.                 {
  26.                         empty_init();
  27.                         for (size_t i = 0; i < n; i++)
  28.                         {
  29.                                 push_back(val);
  30.                         }
  31.                 }
复制代码
三、迭代器

迭代器:类封装节点指针,重载运算符,模拟指针的行为
  1.         template<class T, class Ref, class Ptr>
  2.         struct list_iterator
  3.         {
  4.                 typedef list_node<T> Node;
  5.                 typedef list_iterator<T, Ref, Ptr> Self;
  6.                 Node* _node;
  7.                 list_iterator(Node* node)
  8.                         :_node(node)
  9.                 {}
  10.                 Ref operator*()
  11.                 {
  12.                          return _node->_data;
  13.                 }
  14.                 Ptr operator->()
  15.                 {
  16.                         return &_node->_data;
  17.                 }
  18.                 Self& operator++()
  19.                 {
  20.                         _node = _node->_next;
  21.                         return *this;
  22.                 }
  23.                 Self& operator--()
  24.                 {
  25.                         _node = _node->_prev;
  26.                         return *this;
  27.                 }
  28.                 Self operator++(int)
  29.                 {
  30.                         Self tmp(*this);
  31.                         _node = _node->_next;
  32.                         return tmp;
  33.                 }
  34.                 Self operator--(int)
  35.                 {
  36.                         Self tmp(*this);
  37.                         _node = _node->_prev;
  38.                         return tmp;
  39.                 }
  40.                 bool operator!=(const Self& s)
  41.                 {
  42.                         return _node != s._node;
  43.                 }
  44.                 bool operator==(const Self& s)
  45.                 {
  46.                         return _node == s._node;
  47.                 }
  48.         };
  49.                 typedef list_iterator<T, T&, T*> iterator;
  50.                 typedef list_iterator<T, const T&, const T*> const_iterator;
  51.         iterator begin()
  52.                 {
  53.                         return iterator(_head->_next);
  54.                 }
  55.                 iterator end()
  56.                 {
  57.                         return iterator(_head);
  58.                 }
  59.                 const_iterator begin() const
  60.                 {
  61.                         return const_iterator(_head->_next);
  62.                 }
  63.                 const_iterator end() const
  64.                 {
  65.                         return const_iterator(_head);
  66.                 }
复制代码
四、insert

  1.         iterator insert(iterator pos, const T& val)
  2.                 {
  3.                         Node* cur = pos._node;
  4.                         Node* newnode = new Node(val);
  5.                         Node* prev = cur->_prev;
  6.                         // prev newnode cur
  7.                         prev->_next = newnode;
  8.                         newnode->_prev = prev;
  9.                         newnode->_next = cur;
  10.                         cur->_prev = newnode;
  11.                         ++_size;
  12.                         return iterator(newnode);
  13.                 }
复制代码
五、erase

  1.         iterator erase(iterator pos)
  2.                 {
  3.                         assert(pos != end());
  4.                         Node* del = pos._node;
  5.                         Node* prev = del->_prev;
  6.                         Node* next = del->_next;
  7.                         prev->_next = next;
  8.                         next->_prev = prev;
  9.                         delete del;
  10.                         --_size;
  11.                         return iterator(next);
  12.                 }
复制代码
六、头(尾)插(删)

  1.         void push_back(const T& x)
  2.                 {
  3.                         /*Node* new_node = new Node(x);
  4.                         Node* tail = _head->_prev;
  5.                         tail->_next = new_node;
  6.                         new_node->_prev = tail;
  7.                         new_node->_next = _head;
  8.                         _head->_prev = new_node;*/
  9.                         insert(end(), x);
  10.                 }
  11.                 void push_front(const T& x)
  12.                 {
  13.                         insert(begin(), x);
  14.                 }
  15.                 void pop_front()
  16.                 {
  17.                         erase(begin());
  18.                 }
  19.                 void pop_back()
  20.                 {
  21.                         erase(--end());
  22.                 }
复制代码
七、析构

  1.         ~list()
  2.                 {
  3.                         clear();
  4.                         delete _head;
  5.                         _head = nullptr;
  6.                 }
复制代码
八、赋值运算符重载

  1.         // lt2 = lt3
  2.                 //list& operator=(list lt)
  3.                 list<T>& operator=(list<T> lt)
  4.                 {
  5.                         swap(lt);
  6.                         return *this;
  7.                 }
复制代码
九、clear

  1.         void clear()
  2.                 {
  3.                         auto it = begin();
  4.                         while (it != end())
  5.                         {
  6.                                 it = erase(it);
  7.                         }
  8.                 }
复制代码


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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

卖不甜枣

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表