• 【C++】list


    list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向代。 list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。


    1.list的使用

    1.1list的构造

    list(size_typy 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.2 迭代器

    list是一个带头的双向循环链表

     1.3 list capacity

    empty检测list是否为空
    size返回list中有效结点的个数

    1.4 list element access

    front返回list的第一个结点中值的引用
    back返回list的最后一个节点中值的引用

    1.5 list modifiers

    push_front在list首元素前插入值为val的元素
    pop_front删除list中第一个元素
    push_back在list尾部插入值为val的元素
    pop_back 删除list中最后一个元素
    insert在pos位置中插入值为val的元素
    erase删除pos位置的元素
    swap交换两个list中的元素
    clear清空list中的有效元素

    1.6 迭代器失效

    迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

    2.模拟实现

    list模拟实现的重点就是它的迭代器,list与string、vector不一样,它的底层不是一片连续的空间,所以它不能向string、和vector一样直接取指针,而需要构建一个结构体

    1. template <class T,class Ref,class Ptr>
    2. struct _list_iterator
    3. {
    4. typedef list_node Node;
    5. typedef _list_iterator self;
    6. Node* _node;
    7. _list_iterator (Node* node = Node())
    8. :_node(nullptr)
    9. {
    10. _node = node;
    11. }
    12. //*it
    13. Ref operator*()
    14. {
    15. return _node->_data;
    16. }
    17. Ptr operator->()
    18. {
    19. //return &(operator*());
    20. return &_node->_data;
    21. }
    22. //it1!=it2
    23. bool operator!=(const self& it)
    24. {
    25. return _node != it._node;
    26. }
    27. bool operator==(const self& it)
    28. {
    29. return _node == it._node;
    30. }
    31. //++it
    32. self& operator++()
    33. {
    34. _node = _node->_next;
    35. return *this;
    36. }
    37. //it++
    38. self& operator++(int)
    39. {
    40. self tempIterator = *this;
    41. _node = _node->_next;
    42. return tempIterator;
    43. }
    44. //--it
    45. self& operator--()
    46. {
    47. _node = _node->_prev;
    48. return *this;
    49. }
    50. //it--
    51. self& operator--(int)
    52. {
    53. self tempIterator = *this;
    54. _node = _node->_prev;
    55. return tempIterator;
    56. }
    57. };

    3.list模拟实现总览

    1. #pragma once
    2. #include
    3. using namespace std;
    4. namespace ldx
    5. {
    6. template <class T>
    7. struct list_node
    8. {
    9. list_node(const T& val = T())
    10. :_next(nullptr)
    11. , _prev(nullptr)
    12. , _data(val)
    13. {}
    14. list_node* _next;
    15. list_node* _prev;
    16. T _data;
    17. };
    18. template <class T,class Ref,class Ptr>
    19. struct _list_iterator
    20. {
    21. typedef list_node Node;
    22. typedef _list_iterator self;
    23. Node* _node;
    24. _list_iterator (Node* node = Node())
    25. :_node(nullptr)
    26. {
    27. _node = node;
    28. }
    29. //*it
    30. Ref operator*()
    31. {
    32. return _node->_data;
    33. }
    34. //自定义类型通过迭代器访问成员
    35. Ptr operator->()
    36. {
    37. //return &(operator*());
    38. return &_node->_data;
    39. }
    40. //it1!=it2
    41. bool operator!=(const self& it)
    42. {
    43. return _node != it._node;
    44. }
    45. bool operator==(const self& it)
    46. {
    47. return _node == it._node;
    48. }
    49. //++it
    50. self& operator++()
    51. {
    52. _node = _node->_next;
    53. return *this;
    54. }
    55. //it++
    56. self& operator++(int)
    57. {
    58. self tempIterator = *this;
    59. _node = _node->_next;
    60. return tempIterator;
    61. }
    62. //--it
    63. self& operator--()
    64. {
    65. _node = _node->_prev;
    66. return *this;
    67. }
    68. //it--
    69. self& operator--(int)
    70. {
    71. self tempIterator = *this;
    72. _node = _node->_prev;
    73. return tempIterator;
    74. }
    75. };
    76. template <class T>
    77. class list
    78. {
    79. typedef _list_iterator iterator;
    80. typedef _list_iteratorconst T&, const T*> const_iterator;
    81. typedef list_node Node;
    82. public:
    83. list()
    84. {
    85. empty_init();
    86. }
    87. iterator begin()
    88. {
    89. return iterator(_head->_next);
    90. }
    91. const_iterator begin()const
    92. {
    93. return const_iterator(_head->_next);
    94. }
    95. const_iterator end()const
    96. {
    97. return const_iterator(_head);
    98. }
    99. iterator end()
    100. {
    101. return iterator(_head);
    102. }
    103. void empty_init()
    104. {
    105. _head = new Node;
    106. _head->_next = _head;
    107. _head->_prev = _head;
    108. }
    109. 传统写法
    110. //list(const list& lt)
    111. //{
    112. // _head = new Node;
    113. // _head->_next = _head;
    114. // _head->_prev = _head;
    115. // auto it = lt.begin();
    116. // while (it != lt.end())
    117. // {
    118. // push_back(*it);
    119. // it++;
    120. // }
    121. //}
    122. //现在写法
    123. template <typename InputIterator>
    124. list(InputIterator first, InputIterator last)
    125. {
    126. empty_init();
    127. while (first != last)
    128. {
    129. push_back(*first);
    130. first++;
    131. }
    132. }
    133. void swap(list& lt)
    134. {
    135. std::swap(_head, lt._head);
    136. }
    137. list(const list& lt)
    138. {
    139. empty_init();
    140. list temp(lt.begin(),lt.end());
    141. swap(temp);
    142. }
    143. ~list()
    144. {
    145. clear();
    146. delete _head;
    147. _head = nullptr;
    148. }
    149. list& operator=(list lt)
    150. {
    151. swap(lt);
    152. return *this;
    153. }
    154. void clear()
    155. {
    156. iterator it = begin();
    157. while (it != end())
    158. {
    159. erase(it);
    160. }
    161. }
    162. //在pos前插入节点
    163. void insert(iterator pos, const T& val)
    164. {
    165. Node* cur = pos._node;
    166. Node* new_node = new Node(val);
    167. new_node->_next = cur;
    168. new_node->_prev = cur->_prev;
    169. cur->_prev->_next = new_node;
    170. cur->_prev = new_node;
    171. }
    172. void push_back(const T& val)
    173. {
    174. insert(end(), val);
    175. }
    176. iterator erase(iterator pos)
    177. {
    178. Node* posNext = pos._node->_next;
    179. Node* posPrev = pos._node->_prev;
    180. posPrev->_next = posNext;
    181. posNext->_prev = posPrev;
    182. delete pos._node;
    183. return iterator(posNext);
    184. }
    185. iterator pop_back()
    186. {
    187. return erase(--end());
    188. }
    189. private:
    190. Node* _head;
    191. };
    192. }

  • 相关阅读:
    mac gdb调试失败解决
    Windows 10, version 22H2 (released Oct 2022) 简体中文版、英文版下载
    static_assert
    Rust中的derive属性详解
    USB 协议 (四) USB HOST 侧 的概念详解
    解决IP查询结果偏差的几个方法
    4、QtCharts 做心电图
    centos7安装mysql5.7步骤(图解版)
    新增TOP!10月SCI/SSCI/EI刊源表已更新!
    QNX在车机系统的应用
  • 原文地址:https://blog.csdn.net/holle_world_ldx/article/details/126334278