• list


    一、list的使用

    list实质上就是双向链表,用法和vector、string差不多

    1. int main()
    2. {
    3. list<int> lt1;
    4. lt1.push_back(1);
    5. lt1.push_back(2);
    6. lt1.push_back(3);
    7. lt1.push_front(0);
    8. //遍历
    9. //迭代器
    10. list<int>::iterator it = lt1.begin();
    11. //这里用"!=",是因为end位置是在头哨兵位
    12. while (it != lt1.end())
    13. {
    14. cout << *it << " ";
    15. it++;
    16. }
    17. cout << endl;
    18. //范围for
    19. for (auto e : lt1)
    20. {
    21. cout << e << " ";
    22. }
    23. cout << endl;
    24. //反向迭代器
    25. //list::reverse_iterator rit = lt1.rbegin();
    26. auto rit = lt1.rbegin();
    27. while (rit != lt1.rend())
    28. {
    29. cout << *rit << " ";
    30. rit++;
    31. }
    32. cout << endl;
    33. lt1.pop_front();
    34. lt1.pop_back();
    35. for (auto e : lt1)
    36. {
    37. cout << e << " ";
    38. }
    39. cout << endl;
    40. }

     二、list的模拟实现

    1. namespace Cris
    2. {
    3. //节点
    4. template<class T>
    5. struct list_node
    6. {
    7. list_node* _next;
    8. list_node* _prev;
    9. T _data;
    10. list_node(const T& val = T())
    11. :_next(nullptr)
    12. ,_prev(nullptr)
    13. ,_data(val)
    14. {}
    15. };
    16. //迭代器
    17. // typedef __list_iterator iterator;
    18. // typedef __list_iterator const_iterator;
    19. template<class T, class Ref, class Ptr>
    20. struct _list_iterator
    21. {
    22. typedef list_node Node;
    23. typedef _list_iterator self;
    24. Node* _node;
    25. _list_node(Node* node)
    26. :_node(node)
    27. {}
    28. //析构函数 -- 节点不属于迭代器,不需要迭代器释放
    29. //拷贝构造和赋值重载 -- 默认生成的浅拷贝
    30. Ref operator* ()
    31. {
    32. return _node->_data;
    33. }
    34. Ptr operator->()
    35. {
    36. return &_node->_data;
    37. }
    38. self& operator++()
    39. {
    40. _node = _node->_next;
    41. return *this;
    42. }
    43. self operator++(int)
    44. {
    45. self tmp(*this);
    46. _node = _node->_next;
    47. return tmp;
    48. }
    49. self& operator--()
    50. {
    51. _node = _node->_prev;
    52. return *this;
    53. }
    54. self operator--(int)
    55. {
    56. self tmp(*this);
    57. _node = _node->_prev;
    58. return tmp;
    59. }
    60. bool operator != (const self& it)
    61. {
    62. return _node != it._node;
    63. }
    64. bool operator == (const self& it)
    65. {
    66. return _node == it._node;
    67. }
    68. };
    69. //链表
    70. template<class T>
    71. class list
    72. {
    73. typedef list_node<int> Node;
    74. public:
    75. typedef _list_node iterator;
    76. typedef _list_nodeconst T&, const T*> const_iterator;
    77. const_iterator begin() const
    78. {
    79. return const_iterator(_head->next);
    80. }
    81. const_iterator end() const
    82. {
    83. return const_iterator(_head);
    84. }
    85. iterator begin()
    86. {
    87. return iterator(_head->next);
    88. }
    89. iterator end()
    90. {
    91. return iterator(_head);
    92. }
    93. list()
    94. {
    95. _head = new Node();
    96. _hend->next = _head;
    97. _head->_prev = _head;
    98. }
    99. void empty_init()
    100. {
    101. _head = new Node();
    102. _head->_next = _head;
    103. _head->_prev = _head;
    104. }
    105. template <class InputIterator>
    106. list(InputIterator first, InputIterator last)
    107. {
    108. empty_init();
    109. while (first != last)
    110. {
    111. push_back(*first);
    112. ++first;
    113. }
    114. }
    115. void swap(list& lt)
    116. {
    117. std::swap(_head, lt._head);
    118. }
    119. //lt2(lt1) 现代写法
    120. list(const list& lt)
    121. {
    122. empty_init();
    123. list tmp(lt.begin(), lt.end());
    124. swap(tmp);
    125. }
    126. //lt2 = lt1
    127. list& operator=(list lt)
    128. {
    129. swap(lt);
    130. return *this;
    131. }
    132. ~list()
    133. {
    134. clear();
    135. delete _head;
    136. _head = nullptr;
    137. }
    138. void clear()
    139. {
    140. iterator it = begin();
    141. while (it != end())
    142. {
    143. it = erase(it);
    144. }
    145. }
    146. void push_back(const T& x)
    147. {
    148. /*Node* tail = _head->_prev;
    149. Node* newnode = new Node(x);
    150. tail->_next = newnode;
    151. newnode->_prev = tail;
    152. newnode->_next = _head;
    153. _head->_prev = newnode;*/
    154. insert(end(), x);
    155. }
    156. void push_front(const T& x)
    157. {
    158. insert(begin(), x);
    159. }
    160. void pop_back()
    161. {
    162. //end() 是头哨兵位,--就是list的尾
    163. erase(--end());
    164. }
    165. void pop_front()
    166. {
    167. erase(begin());
    168. }
    169. //插入在pos位置之前
    170. iterator insert(iterator pos, const T& x)
    171. {
    172. Node* newNode = new Node(x);
    173. Node* cur = pos._node;
    174. Node* prev = cur->_prev;
    175. prev->_next = newNode;
    176. newNode->_prev = prev;
    177. newNode->_next = cur;
    178. cur->_prev = newNode;
    179. return iterator(newNode);
    180. }
    181. iterator erase(iterator pos)
    182. {
    183. assert(pos != end());
    184. Node* cur = pos._node;
    185. Node* prev = cur->_prev;
    186. Node* next = cur->_next;
    187. prev->_next = next;
    188. next->_prev = prev;
    189. delete cur;
    190. return iterator(next);
    191. }
    192. private:
    193. Node* _head;
    194. };
    195. }

    迭代器失效问题:

    因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
    1. int main()
    2. {
    3. int arr[] = { 1,2,3,4,5,6,7,8,9 };
    4. Cris::list<int> lt(arr, arr + (sizeof(arr) / sizeof(arr[0])));
    5. auto it = lt.begin();
    6. while (it != lt.end())
    7. {
    8. //erase()函数执行后,it所指向的节点已被删除
    9. //因此it无效,在下一次使用it时,必须先给其赋值
    10. it = lt.erase(it);
    11. }
    12. return 0;
    13. }


     

  • 相关阅读:
    java毕业设计基于精细化考核的离散数学课程教学目标达成系统Mybatis+系统+数据库+调试部署
    银行卡二元素api接口是怎么完成验证的?
    记录:树莓派 安装opencv 完整的艰辛过程
    什么软件可以把真人照片卡通化、动漫化?
    区块链 | ERC721 标准
    C语言-----qsort函数的功能以及模拟实现
    python+pygame+opencv+gpt实现虚拟数字人直播(一)
    数据结构题目收录(六)
    倒计时15天!百度世界2023抢先看
    Vue3学习:如何在Vue3项目中创建一个axios实例
  • 原文地址:https://blog.csdn.net/qq_61434514/article/details/126168976