C++STl——list

[复制链接]
发表于 2025-9-16 01:24:08 | 显示全部楼层 |阅读模式

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

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

×
list的细节

list的细节之一就是其迭代器没有利用指针了,由于指针是无法到达迭代器的效果的,再增补下迭代器的范例,迭代器分为单向,双向,随机迭代器,单向迭代器的容器有forward_list,unordered_map等,单向迭代器只支持++,双向迭代器有list,map,双向迭代器支持++与–,随机迭代器有string,vector,deque支持++,–,+,-,迭代器的名字决定了其范例,list本身是有sort函数的,但是服从过低,不如将他粘贴到vector进行sort在粘贴返来,后续有代码证实。list也存在迭代器失效问题,list的insert相比于vector是没有失效问题的,由于list的insert不存在扩容问题,根本全部的erase都有迭代器失效问题,以是每个erase都会返回删除下一个位置的迭代器,string也是有的,只是string更风俗用[]而不是迭代器进行访问。
头文件

  1. #pragma once
  2. #include<assert.h>
  3. namespace prime
  4. {
  5.         template<class T>
  6.         struct list_node
  7.         {
  8.                 list_node* _next;
  9.                 list_node* _prev;
  10.                 T _data;
  11.                 list_node(const T& x = T())
  12.                         :_next(nullptr)
  13.                         , _prev(nullptr)
  14.                         , _data(x)
  15.                 {}
  16.         };
  17.         //这里是封装了iterator类,因为list的原生指针无法作为迭代器
  18.         // typedef list_iterator<T, T&, T*> iterator;三个模版参数,是为了后面的const做铺垫
  19.         // 如果需要const迭代器,我们是没办法完成的,所以这里封装一个const_iterator,由于普通ite与const的区别
  20.         // 就只有*上,所以就通过添加参数来进行合并
  21.         // typedef list_iterator<T, const T&, const T*> const_iterator;
  22.         template<class T, class Ref, class Ptr>
  23.         struct list_iterator
  24.         {
  25.                 typedef list_node<T> Node;
  26.                 typedef list_iterator<T, Ref, Ptr> Self;
  27.                 Node* _node;
  28.                 list_iterator(Node* node)
  29.                         :_node(node)
  30.                 {}
  31.                 Ref operator*()
  32.                 {
  33.                         return _node->_data;
  34.                 }
  35.                 Ptr operator->()
  36.                 {
  37.                         return &_node->_data;
  38.                 }
  39.                 Self& operator++()
  40.                 {
  41.                         _node = _node->_next;
  42.                         return *this;
  43.                 }
  44.                 Self operator++(int)//因为tmp会销毁,所以不能传引用
  45.                 {
  46.                         Self tmp(*this);
  47.                         _node = _node->_next;
  48.                         return tmp;
  49.                 }
  50.                 Self& operator--()
  51.                 {
  52.                         _node = _node->_prev;
  53.                         return *this;
  54.                 }
  55.                 Self operator--(int)
  56.                 {
  57.                         Self tmp(*this);
  58.                         _node = _node->_prev;
  59.                         return tmp;
  60.                 }
  61.                 bool operator!=(const Self& s) const
  62.                 {
  63.                         return _node != s._node;
  64.                 }
  65.                 bool operator==(const Self& s) const
  66.                 {
  67.                         return _node == s._node;
  68.                 }
  69.         };
  70.         /*template<class T>
  71.         struct list_const_iterator
  72.         {
  73.                 typedef list_node<T> Node;
  74.                 typedef list_const_iterator<T> Self;
  75.                 Node* _node;
  76.                 list_const_iterator(Node* node)
  77.                         :_node(node)
  78.                 {}
  79.                 const T& operator*()
  80.                 {
  81.                         return _node->_data;
  82.                 }
  83.                 Self& operator++()
  84.                 {
  85.                         _node = _node->_next;
  86.                         return *this;
  87.                 }
  88.                 Self operator++(int)
  89.                 {
  90.                         Self tmp(*this);
  91.                         _node = _node->_next;
  92.                         return tmp;
  93.                 }
  94.                 Self& operator--()
  95.                 {
  96.                         _node = _node->_prev;
  97.                         return *this;
  98.                 }
  99.                 Self operator--(int)
  100.                 {
  101.                         Self tmp(*this);
  102.                         _node = _node->_prev;
  103.                         return tmp;
  104.                 }
  105.                 bool operator!=(const Self& s) const
  106.                 {
  107.                         return _node != s._node;
  108.                 }
  109.                 bool operator==(const Self& s) const
  110.                 {
  111.                         return _node == s._node;
  112.                 }
  113.         };*/
  114.         template<class T>
  115.         class list
  116.         {
  117.                 typedef list_node<T> Node;
  118.         public:
  119.                 typedef list_iterator<T, T&, T*> iterator;
  120.                 //typedef list_const_iterator<T> const_iterator;
  121.                 typedef list_iterator<T, const T&, const T*> const_iterator;
  122.                 iterator begin()
  123.                 {
  124.                         return iterator(_head->_next);
  125.                 }
  126.                 iterator end()
  127.                 {
  128.                         return iterator(_head);
  129.                 }
  130.                 const_iterator begin() const
  131.                 {
  132.                         return const_iterator(_head->_next);
  133.                 }
  134.                 const_iterator end() const
  135.                 {
  136.                         return const_iterator(_head);
  137.                 }
  138.                 //这里单独封装一个初始化函数不选择用初始化列表进行初始化,是因为后续需要额外创建链表时需要初始化
  139.                 //初始化头节点需要创建Node对象并设置其_next和_prev指针指向自身。
  140.                 //这类多步操作无法直接在构造函数的初始化列表中完成(初始化列表仅支持表达式,不支持语句)
  141.                 void empty_init()
  142.                 {
  143.                         _head = new Node;
  144.                         _head->_next = _head;
  145.                         _head->_prev = _head;
  146.                         _size = 0;
  147.                 }
  148.                 list()
  149.                 {
  150.                         empty_init();
  151.                 }
  152.                 list(initializer_list<T> il)
  153.                 {
  154.                         empty_init();
  155.                         for (auto& e : il)
  156.                         {
  157.                                 push_back(e);
  158.                         }
  159.                 }
  160.                 // lt2(lt1)
  161.                 //list(const list<T>& lt)
  162.                 list(list<T>& lt)
  163.                 {
  164.                         empty_init();
  165.                         for (auto& e : lt)
  166.                         {
  167.                                 push_back(e);
  168.                         }
  169.                 }
  170.                 void swap(list<T>& lt)
  171.                 {
  172.                         std::swap(_head, lt._head);
  173.                         std::swap(_size, lt._size);
  174.                 }
  175.                 // lt1 = lt3
  176.                 list<T>& operator=(list<T> lt)
  177.                 {
  178.                         swap(lt);
  179.                         return *this;
  180.                 }
  181.                 ~list()
  182.                 {
  183.                         clear();
  184.                         delete _head;
  185.                         _head = nullptr;
  186.                 }
  187.                 void clear()
  188.                 {
  189.                         auto it = begin();
  190.                         while (it != end())
  191.                         {
  192.                                 it = erase(it);
  193.                         }
  194.                 }
  195.                 size_t size()
  196.                 {
  197.                         return _size;
  198.                 }
  199.                 void push_back(const T& x)
  200.                 {
  201.                         /*Node* tail = _head->_prev;
  202.                         Node* newnode = new Node(x);
  203.                         tail->_next = newnode;
  204.                         newnode->_prev = tail;
  205.                         newnode->_next = _head;
  206.                         _head->_prev = newnode;*/
  207.                         insert(end(), x);
  208.                 }
  209.                 void push_front(const T& x)
  210.                 {
  211.                         insert(begin(), x);
  212.                 }
  213.                 void pop_back()
  214.                 {
  215.                         erase(--end());
  216.                 }
  217.                 void pop_front()
  218.                 {
  219.                         erase(begin());
  220.                 }
  221.                 void insert(iterator pos, const T& x)
  222.                 {
  223.                         Node* cur = pos._node;
  224.                         Node* prev = cur->_prev;
  225.                         Node* newnode = new Node(x);
  226.                         // prev newnode cur
  227.                         prev->_next = newnode;
  228.                         newnode->_prev = prev;
  229.                         newnode->_next = cur;
  230.                         cur->_prev = newnode;
  231.                         ++_size;
  232.                 }
  233.                 iterator erase(iterator pos)
  234.                 {
  235.                         assert(pos != end());
  236.                         Node* cur = pos._node;
  237.                         Node* prev = cur->_prev;
  238.                         Node* next = cur->_next;
  239.                         prev->_next = next;
  240.                         next->_prev = prev;
  241.                         delete cur;
  242.                         --_size;
  243.                         //return iterator(next);
  244.                         return next;
  245.                 }
  246.         private:
  247.                 Node* _head;
  248.                 size_t _size;
  249.         };
  250.         void test_list1()
  251.         {
  252.                 list<int> lt;
  253.                 lt.push_back(1);
  254.                 lt.push_back(2);
  255.                 lt.push_back(3);
  256.                 lt.push_back(4);
  257.                 list<int>::iterator it = lt.begin();
  258.                 while (it != lt.end())
  259.                 {
  260.                         *it += 10;
  261.                         cout << *it << " ";
  262.                         ++it;
  263.                 }
  264.                 cout << endl;
  265.                 lt.push_front(1);
  266.                 lt.push_front(2);
  267.                 lt.push_front(3);
  268.                 lt.push_front(4);
  269.                 for (auto e : lt)
  270.                 {
  271.                         cout << e << " ";
  272.                 }
  273.                 cout << endl;
  274.                 lt.pop_back();
  275.                 lt.pop_back();
  276.                 lt.pop_front();
  277.                 lt.pop_front();
  278.                 for (auto e : lt)
  279.                 {
  280.                         cout << e << " ";
  281.                 }
  282.                 cout << endl;
  283.         }
  284.         void test_list2()
  285.         {
  286.                 list<int> lt;
  287.                 lt.push_back(1);
  288.                 lt.push_back(2);
  289.                 lt.push_back(3);
  290.                 lt.push_back(4);
  291.                 list<int>::iterator it = lt.begin();
  292.                 while (it != lt.end())
  293.                 {
  294.                         if (*it % 2 == 0)
  295.                         {
  296.                                 it = lt.erase(it);
  297.                         }
  298.                         else
  299.                         {
  300.                                 ++it;
  301.                         }
  302.                 }
  303.                 for (auto e : lt)
  304.                 {
  305.                         cout << e << " ";
  306.                 }
  307.                 cout << endl;
  308.         }
  309.         // const T* p1;
  310.         // T* const p2;
  311.         void print(const list<int>& lt)
  312.         {
  313.                 // const迭代器的要求不是本身不能修改,而是指向的内容不能修改
  314.                 //const list<int>::iterator it = lt.begin();
  315.                 list<int>::const_iterator it = lt.begin();
  316.                 while (it != lt.end())
  317.                 {
  318.                         // *it = 10;
  319.                         cout << *it << " ";
  320.                         ++it;
  321.                 }
  322.                 cout << endl;
  323.         }
  324.         void test_list3()
  325.         {
  326.                 list<int> lt1;
  327.                 lt1.push_back(1);
  328.                 lt1.push_back(2);
  329.                 lt1.push_back(3);
  330.                 lt1.push_back(4);
  331.                 for (auto e : lt1)
  332.                 {
  333.                         cout << e << " ";
  334.                 }
  335.                 cout << endl;
  336.                 list<int> lt2(lt1);
  337.                 for (auto e : lt2)
  338.                 {
  339.                         cout << e << " ";
  340.                 }
  341.                 cout << endl;
  342.                 list<int> lt3 = { 1,2,3,4,5,6 };
  343.                 lt1 = lt3;
  344.                 for (auto e : lt1)
  345.                 {
  346.                         cout << e << " ";
  347.                 }
  348.                 cout << endl;
  349.         }
  350.         struct AA
  351.         {
  352.                 int _a1;
  353.                 int _a2;
  354.                 AA(int a1 = 1, int a2 = 1)
  355.                         :_a1(a1)
  356.                         , _a2(a2)
  357.                 {}
  358.         };
  359.         void test_list4()
  360.         {
  361.                 //AA aa1 = { 1,1 };
  362.                 vector<AA> v1;
  363.                 v1.push_back({ 1,1 });
  364.                 v1.push_back({ 2,2 });
  365.                 v1.push_back({ 3,3 });
  366.                 vector<AA>::iterator it1 = v1.begin();
  367.                 while (it1 != v1.end())
  368.                 {
  369.                         cout << it1->_a1 << ":" << it1->_a2 << endl;
  370.                         ++it1;
  371.                 }
  372.                 cout << endl;
  373.                 list<AA> lt1;
  374.                 lt1.push_back({ 1,1 });
  375.                 lt1.push_back({ 2,2 });
  376.                 lt1.push_back({ 3,3 });
  377.                 list<AA>::iterator lit1 = lt1.begin();
  378.                 while (lit1 != lt1.end())
  379.                 {
  380.                         //cout << (*lit1)._a1 <<":"<< (*lit1)._a2 << endl;
  381.                         // 特殊处理,省略了一个->,为了可读性
  382.                         cout << lit1->_a1 << ":" << lit1->_a2 << endl;
  383.                         cout << lit1.operator->()->_a1 << ":" << lit1.operator->()->_a2 << endl;
  384.                         ++lit1;
  385.                 }
  386.                 cout << endl;
  387.         }
  388. }
复制代码
源码

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include<list>
  4. #include<vector>
  5. #include<algorithm>
  6. using namespace std;
  7. //int main()
  8. //{
  9. //        // 21:05
  10. //        list<int> lt1 = {1,2,2,2,3,3,4,2,3,5,6};
  11. //        for (auto e : lt1)
  12. //        {
  13. //                cout << e << " ";
  14. //        }
  15. //        cout << endl;
  16. //        sort(lt1.begin(), lt1.end());
  17. //
  18. //        /*lt1.sort();
  19. //        lt1.unique();*/
  20. //        lt1.remove(2);
  21. //        for (auto e : lt1)
  22. //        {
  23. //                cout << e << " ";
  24. //        }
  25. //        cout << endl;
  26. //
  27. //        return 0;
  28. //}
  29. void test_op1()
  30. {
  31.         srand(time(0));
  32.         const int N = 1000000;
  33.         list<int> lt1;
  34.         vector<int> v;
  35.         for (int i = 0; i < N; ++i)
  36.         {
  37.                 auto e = rand() + i;
  38.                 lt1.push_back(e);
  39.                 v.push_back(e);
  40.         }
  41.         int begin1 = clock();
  42.         // 排序
  43.         sort(v.begin(), v.end());
  44.         int end1 = clock();
  45.         int begin2 = clock();
  46.         lt1.sort();
  47.         int end2 = clock();
  48.         printf("vector sort:%d\n", end1 - begin1);
  49.         printf("list sort:%d\n", end2 - begin2);
  50. }
  51. void test_op2()
  52. {
  53.         srand(time(0));
  54.         const int N = 1000000;
  55.         list<int> lt1;
  56.         list<int> lt2;
  57.         for (int i = 0; i < N; ++i)
  58.         {
  59.                 auto e = rand() + i;
  60.                 lt1.push_back(e);
  61.                 lt2.push_back(e);
  62.         }
  63.         int begin1 = clock();
  64.         // 拷贝vector
  65.         vector<int> v(lt2.begin(), lt2.end());
  66.         // 排序
  67.         sort(v.begin(), v.end());
  68.         // 拷贝回lt2
  69.         lt2.assign(v.begin(), v.end());
  70.         int end1 = clock();
  71.         int begin2 = clock();
  72.         lt1.sort();
  73.         int end2 = clock();
  74.         printf("list copy vector sort copy list sort:%d\n", end1 - begin1);
  75.         printf("list sort:%d\n", end2 - begin2);
  76. }
  77. void test_list1()
  78. {
  79.         // 一个链表的节点移动到另一个链表
  80.         std::list<int> lt1 = { 1, 2, 3, 4, 5 };
  81.         std::list<int> lt2 = { 10, 20, 30, 40 };
  82.         for (auto e : lt1)
  83.         {
  84.                 cout << e << " ";
  85.         }
  86.         cout << endl;
  87.         for (auto e : lt2)
  88.         {
  89.                 cout << e << " ";
  90.         }
  91.         cout << endl;
  92.         lt1.splice(lt1.begin(), lt2);
  93.         for (auto e : lt1)
  94.         {
  95.                 cout << e << " ";
  96.         }
  97.         cout << endl;
  98.         for (auto e : lt2)
  99.         {
  100.                 cout << e << " ";
  101.         }
  102.         cout << endl;
  103.         // 一个链表中节点调整顺序
  104.         std::list<int> lt3 = { 1, 2, 3, 4, 5 };
  105.         int x;
  106.         cin >> x;
  107.         auto it = find(lt3.begin(), lt3.end(), x);
  108.         if (it != lt3.end())
  109.         {
  110.                 lt3.splice(lt3.begin(), lt3, it);
  111.         }
  112.         for (auto e : lt3)
  113.         {
  114.                 cout << e << " ";
  115.         }
  116.         cout << endl;
  117. }
  118. #include"List.h"
  119. int main()
  120. {
  121.         prime::test_list4();
  122.         return 0;
  123. }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表