经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++之list容器模拟实现方式
来源:jb51  时间:2023/2/8 8:56:38  对本文有异议

总述

list模拟实现主要包括四个类:节点类、迭代器类、反向迭代器类、list类

list底层结构:

因为list的底层空间不连续,所以迭代器不能使用原生态的指针,将节点类型的指针封装成类,重载解引用及自增等常用操作。list可以保存多种数据类型,所以这些类都写成类模板

一、节点类

list底层是带头结点的双向循环链表,先实现节点类,给成类模板的形式,便于插入不同类型的数据。

  1. template<class T>
  2. struct ListNode
  3. {
  4. ListNode<T>* prev;
  5. ListNode<T>* next;
  6. T data;//要在链表中保存的数据类型
  7.  
  8. ListNode(const T& value = T())
  9. :prev(nullptr)
  10. , next(nullptr)
  11. , data(value)
  12. { }
  13. };

定义新节点的方法:

  1. ListNode<变量类型>*变量名=new ListNode(value);

二、迭代器类

迭代器类模板有三个参数

  • T:迭代器指向的元素类型
  • Ref:返回的引用类型
  • Ptr:返回的指针类型

Ref和Ptr一般不写成T&和T*。

成员变量

迭代器类的成员变量就是节点类型的指针

  1. Node* _pNode;//成员变量,节点类型指针

构造函数

编译器默认的构造函数是无参的,构造函数需要给出

  1. ListIterator(Node* pNode = nullptr)
  2. :_pNode(pNode)
  3. {}

*重载

返回节点中保存的数据

  1. Ref operator*()
  2. {
  3. return _pNode->data;
  4. }

->重载

返回节点中保存的数据的地址

  1. Ptr operator->()
  2. {
  3. return &_pNode->data;
  4. }

->的重载只对内置类型有意义:

“++”

前置++

返回值是迭代器自身类型的引用,前面已经将ListIterator<T, Ref, Ptr>重命名位Self,表示迭代器自身的类型。

  1. Self& operator++()
  2. {
  3. _pNode = _pNode->next;
  4. return *this;
  5. }

后置++

定义临时变量,返回自增前的值

  1. Self operator++(int)
  2. {
  3. Self temp(*this);
  4. _pNode = _pNode->next;
  5. return temp;
  6. }

“–”

与++原理相同

  1. Self& operator--()
  2. {
  3. _pNode = _pNode->prev;
  4. return (*this);
  5. }
  6. Self operator--(int)
  7. {
  8. Self temp(*this);
  9. _pNode = _pNode->prev;
  10. return temp;
  11. }

“==“和”!=”

比较两个迭代器中封装的指针

  1. bool operator!=(const Self& it)
  2. {
  3. return _pNode != it._pNode;
  4. }
  5. bool operator==(const Self& it)
  6. {
  7. return _pNode == it._pNode;
  8. }

三、反向迭代器类

反向迭代器可以对迭代器类进行复用

因为类外访问静态成员变量时也会使用类名::变量名的方式,所以对迭代器类中的Reference和Pointer进行重命名时要加上typename,明确告诉编译器要重命名的是一个数据类型。否则编译器会报错:

成员变量

反向迭代器对迭代器类进行复用

  1. private:
  2. Iterator _it;//正向迭代器

*重载

反向迭代器的解引用要做特殊处理,返回的是对迭代器–的值

  1. Reference operator*()
  2. {
  3. //*做特殊处理,先--,再解引用返回
  4. auto temp = _it;
  5. --temp;
  6. return *temp;
  7. }

->重载

复用*的重载,返回value的地址

  1. Pointer operator->()
  2. {
  3. return &(operator*());
  4. }

“++”

反向迭代器的++即为正向迭代器的–

  1. Self operator++()
  2. {
  3. --_it;
  4. return *this;
  5. }
  6. Self operator++(int)
  7. {
  8. Self temp(*this);
  9. --_it;
  10. return *this;
  11. }

“- -”

反向迭代器的–用正向迭代器的++替代

  1. Self operator--()
  2. {
  3. ++_it;
  4. return *this;
  5. }
  6. Self operator--(int)
  7. {
  8. Self temp(*this);
  9. ++_it;
  10. return temp;
  11. }

" == " 和"!="

比较反向迭代器类中保存的正向迭代器,复用正向迭代器中的比较方法

  1. bool operator==(const Self& rit)
  2. {
  3. return _it == rit;
  4. }
  5. bool operator!=(const Self& rit)
  6. {
  7. return _it == rit._it;
  8. }

四、list类

成员变量

list的成员变量只有一个head指针,指向链表的第一个节点

  1. private:
  2. Node* head;

构造相关

空对象

  1. list()
  2. {
  3. CreatHead();
  4. }

创造头节点的方法:

  1. //提供一个创造头结点的方法
  2. void CreatHead()
  3. {
  4. //调用节点类的构造方法
  5. head = new Node();
  6. head->next = head;
  7. head->prev = head;
  8. }
  1. 0000000

new申请空间,令head指向这段空间,head的next和prev都指向自己。

n个T类型元素

调用push_back方法,创造头节点后,不断进行尾插直到元素个数等于n

  1. list(int n, const T& value = T())
  2. {
  3. CreatHead();
  4. for (int i = 0; i < n; ++i)
  5. {
  6. push_back(value);
  7. }
  8. }

拷贝构造

复用push_back

  1. list(const list<T>& l)
  2. {
  3. CreatHead();
  4. auto it = l.cbegin();
  5. while (it != l.cend())
  6. {
  7. push_back(*it);
  8. it++;
  9. }
  10. }

迭代器构造

将迭代器构造方法写成函数模板,可以传入不同类型的迭代器来构造list对象

  1. template<class InputIterator>
  2. list(InputIterator first, InputIterator last)
  3. {
  4. CreatHead();
  5. while (first != last)
  6. {
  7. push_back(*first);
  8. first++;
  9. }
  10. }

赋值运算符重载

与拷贝构造写法相同

  1. list<T>& operator=(const list<T>& l)
  2. {
  3. if (this != &l)
  4. {
  5. clear();//先清空当前对象中的节点
  6. auto it = l.cbegin();
  7. while (it != l.cend())
  8. {
  9. push_back(*it);
  10. it++;
  11. }
  12. }
  13. return *this;
  14. }

析构

清空当前对象,释放头节点空间,将头节点置空

  1. ~list()
  2. {
  3. clear();
  4. delete head;
  5. head = nullptr;
  6. }

迭代器

正向迭代器

begin

此处的iterator是对ListIterator<T, T&, T*>的重命名,这里会返回一个ListIterator<T, T&, T*>类对象

  1. iterator begin()
  2. {
  3. //iterator it(head->next);
  4. //return it;
  5. //head->next是传递给迭代器类对象构造函数的参数,调用iterator的构造函数
  6. return iterator(head->next);//构造匿名对象返回
  7. }

end

  1. iterator end()
  2. {
  3. return iterator(head);
  4. }

const类型迭代器

iterator和const_iterator 是两个不同的类:

两者使用的是相同的类模板,但是传递的参数不同,最终实例化的也是不同的类。 

cbegin&cend

  1. const_iterator cbegin()const
  2. {
  3. return const_iterator(head->next);
  4. }
  5. const_iterator cend()const
  6. {
  7. return const_iterator(head);
  8. }

反向迭代器

rbegin&rend

返回正向迭代器的end和begin

  1. reverse_iterator rbegin()
  2. {
  3. ?? ?return reverse_iterator(end());
  4. }
  5. reverse_iterator rend()
  6. {
  7. ?? ?return reverse_iterator(begin());
  8. }

crbegin&crend

复用正向迭代器的cend和cbegin

  1. const_reverse_iteraotr crbegin()const
  2. {
  3. ?? ?return const_reverse_iteraotr(cend());
  4. }
  5. const_reverse_iteraotr crend()const
  6. {
  7. ?? ?return const_reverse_iteraotr(cbegin());
  8. }

容量操作

size

遍历链表,统计节点个数

  1. size_t size()
  2. {
  3. ?? ?auto it = cbegin();
  4. ?? ?size_t count = 0;
  5. ?? ?while (it != cend())
  6. ?? ?{
  7. ?? ??? ?++count;
  8. ?? ??? ?++it;
  9. ?? ?}
  10. ?? ?return count;
  11. }

empty

如果head->next是head本身则表明链表为空

  1. bool empty()
  2. {
  3. ?? ?return head->next == head;
  4. }

 

resize

改变节点个数,若新的节点个数大于旧的,则调用push_back填充元素;若新的节点个数小于原来的调用pop_back尾删

元素访问

front

复用迭代器解引用的方法,返回begin()位置元素

  1. T& front()
  2. {
  3. return *begin();
  4. }
  5. const T& front()const
  6. {
  7. return *cbegin();
  8. }

back

back表示最后一个元素,但是end()指向的是最后一个元素的下一个位置,需要定义临时变量,不能直接对end()进行- -。

  1. T& back()
  2. {
  3. auto it = end();
  4. //return --end()//错误写法
  5. it--;
  6. return *it;
  7. }
  8. const T& back()const
  9. {
  10. auto it = end();
  11. it--;
  12. return *it;
  13. }

打印链表

定义一个打印链表的函数模板,检验方法。通过迭代器遍历链表,打印每一个节点的数据。

  1. template<class T>
  2. void PrintList(const list<T>& l)
  3. {
  4. auto it = l.cbegin();
  5. while (it != l.cend())
  6. {
  7. cout << *it << " ";
  8. ++it;
  9. }
  10. cout << endl;
  11. }

元素修改

尾插与尾删

push_back

复用insert方法在end位置插入

  1. void push_back(const T& value)
  2. {
  3. insert(end(), value);
  4. }

pop_back

先判断链表是否为空,复用erase方法在end的前一个位置进行插入

  1. void pop_back()
  2. {
  3. if (empty())
  4. {
  5. return;
  6. }
  7. auto it = end();
  8. it--;
  9. erase(it);
  10. }

头插与头删

复用insert与erase方法,在begin()位置进行插入或删除

  1. void push_front(const T& value = T())
  2. {
  3. insert(begin(), value);
  4. }
  5. void pop_front()
  6. {
  7. erase(begin());
  8. }

?insert

任意位置的插入:申请新节点,连接新节点与链表,断开旧的连接。

这里传入的参数是一个迭代器类对象,不能直接进行操作,要对对象中封装的_pNode指针进行操作。

返回值是新插入的节点的迭代器,所以要用申请的新节点的指针newnode构造一个迭代器类对象返回,不能直接返回newnode

  1. iterator insert(iterator Insertpos, const T& value)
  2. {
  3. Node* newnode = new Node(value);
  4. Node* pos = Insertpos._pNode;//_pNode是节点类型的指针
  5. newnode->next = pos;
  6. newnode->prev = pos->prev;
  7. newnode->prev->next = newnode;
  8. pos->prev = newnode;
  9. //return newnode;
  10. //?迭代器是封装的Node*指针,此时不能再返回newnode
  11. return iterator(newnode);//构造匿名对象返回
  12. }

?erase

任意位置的删除:分别改变前后两个节点的next和prev指针的指向即可

  1. iterator erase(iterator Erasepos)
  2. {
  3. Node* pos = Erasepos._pNode;
  4. Node* ret = pos->next;
  5. pos->prev->next = pos->next;
  6. pos->next->prev = pos->prev;
  7. delete pos;
  8. return iterator(ret);
  9. }

区间删除:复用单个节点删除的方法,遍历要删除的区间。

要用接收erase的返回值,防止迭代器失效

  1. iterator erase(iterator first, iterator last)
  2. {
  3. auto it = first;
  4. while (it != last)
  5. {
  6. //it=erase(it);
  7. //后置++会构造临时对象返回,不会导致迭代器失效
  8. erase(it++);
  9. }
  10. return it;
  11. }

clear&swap

  • clear复用erase区间删除的方法,从begin删除到end位置;
  • swap方法调用标准库中的swap,交换两个链表的头节点。
  1. void clear()
  2. {
  3. erase(begin(), end());
  4. }
  5. void swap(list<T>& l)
  6. {
  7.  
  8. std::swap(head, l.head);
  9. }

附:完整list类,含测试用例

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4.  
  5. namespace ZH
  6. {
  7. /
  8. //节点类模板,
  9. template<class T>
  10. struct ListNode
  11. {
  12. ListNode<T>* prev;
  13. ListNode<T>* next;
  14. T data;
  15.  
  16. ListNode(const T& value = T())
  17. :prev(nullptr)
  18. , next(nullptr)
  19. , data(value)
  20. { }
  21. };
  22. /
  23. //迭代器类模板
  24. //list的迭代器不能使用原生态的指针,要进行封装
  25. //T:迭代器指向的元素类型
  26. //Ref:给operator*使用,返回引用类型,不要写成T&
  27. //Ptr:返回值使用,不要写成T*
  28. template<class T,class Ref,class Ptr>
  29. class ListIterator
  30. {
  31. public:
  32. typedef ListNode<T> Node;//化简节点类的名字
  33. typedef Ref Reference;//在反向迭代器类中使用
  34. typedef Ptr Pointer;
  35.  
  36. typedef ListIterator<T, Ref, Ptr> Self;//简化迭代器类的名字
  37.  
  38. //构造函数
  39. ListIterator(Node* pNode=nullptr)
  40. :_pNode(pNode)
  41. {}
  42.  
  43. //重载部分需要使用的运算符即可:*、->、++、--、==
  44. Ref operator*()
  45. {
  46. return _pNode->data;
  47. }
  48. //T为自定义类型时有意义,
  49. Ptr operator->()
  50. {
  51. return &_pNode->data;
  52. }
  53. //前置++,返回值是迭代器自身类型的引用
  54. Self& operator++()
  55. {
  56. _pNode = _pNode->next;
  57. return *this;
  58. }
  59. //后置
  60. Self operator++(int)
  61. {
  62. Self temp(*this);
  63. _pNode = _pNode->next;
  64. return temp;
  65. }
  66. Self& operator--()
  67. {
  68. _pNode = _pNode->prev;
  69. return (*this);
  70. }
  71. Self operator--(int)
  72. {
  73. Self temp(*this);
  74. _pNode = _pNode ->prev;
  75. return temp;
  76. }
  77. //迭代器能进行比较
  78. bool operator!=(const Self& it)
  79. {
  80. return _pNode != it._pNode;
  81. }
  82. bool operator==(const Self& it)
  83. {
  84. return _pNode == it._pNode;
  85. }
  86.  
  87. Node* _pNode;//成员变量,节点类型指针
  88. };
  89.  
  90. //反向迭代器类模板,对迭代器进行复用
  91. template<class Iterator>
  92. class ListReverseIterator
  93. {
  94. public:
  95. //typedef Iterator::Reference Reference;
  96. //typedef Iterator::Pointer Pointer;
  97. typedef typename Iterator::Reference Reference;//typename指定Reference是Iterator中的数据类型
  98. typedef typename Iterator::Pointer Pointer;
  99. typedef ListReverseIterator<Iterator> Self;
  100.  
  101. ListReverseIterator(Iterator it)
  102. : _it(it)
  103. { }
  104.  
  105. Reference operator*()
  106. {
  107. //*做特殊处理,先--,再解引用返回
  108. auto temp = _it;
  109. --temp;
  110. return *temp;
  111. }
  112. Pointer operator->()
  113. {
  114. return &(operator*());
  115. }
  116. Self operator++()
  117. {
  118. --_it;
  119. return *this;
  120. }
  121. Self operator++(int)
  122. {
  123. Self temp(*this);
  124. --_it;
  125. return *this;
  126. }
  127. Self operator--()
  128. {
  129. ++_it;
  130. return *this;
  131. }
  132. Self operator--(int)
  133. {
  134. Self temp(*this);
  135. ++_it;
  136. return temp;
  137. }
  138. bool operator==(const Self& rit)
  139. {
  140. return _it == rit;
  141. }
  142. bool operator!=(const Self& rit)
  143. {
  144. return _it == rit._it;
  145. }
  146.  
  147. private:
  148. Iterator _it;//正向迭代器
  149. };
  150.  
  151. template<class T>
  152. class list
  153. {
  154. typedef ListNode<T> Node;
  155. //typedef Node* iterator;//不能使用Node*作迭代器
  156. //迭代器
  157. typedef ListIterator<T, T&, T*> iterator;
  158. typedef ListIterator< T, const T&, const T*> const_iterator;
  159. typedef ListReverseIterator<iterator> reverse_iterator;
  160. typedef ListReverseIterator<const_iterator> const_reverse_iteraotr;
  161.  
  162. public:
  163. ///
  164. //构造
  165. list()
  166. {
  167. CreatHead();
  168. }
  169. list(int n, const T& value=T())
  170. {
  171. CreatHead();
  172. for (int i = 0; i < n; ++i)
  173. {
  174. push_back(value);
  175. }
  176. }
  177. list(const list<T>& l)
  178. {
  179. CreatHead();
  180. auto it = l.cbegin();
  181. while (it != l.cend())
  182. {
  183. push_back(*it);
  184. it++;
  185. }
  186. }
  187. //迭代器区间构造
  188. template<class InputIterator>
  189. list(InputIterator first, InputIterator last)
  190. {
  191. CreatHead();
  192. while (first != last)
  193. {
  194. push_back(*first);
  195. first++;
  196. }
  197. }
  198. //赋值运算符重载
  199. list<T>& operator=(const list<T>& l)
  200. {
  201. if (this != &l)
  202. {
  203. clear();//先清空当前对象中的节点
  204. auto it = l.cbegin();
  205. while (it != l.cend())
  206. {
  207. push_back(*it);
  208. it++;
  209. }
  210. }
  211. return *this;
  212. }
  213. ~list()
  214. {
  215. clear();
  216. delete head;
  217. head = nullptr;
  218. }
  219. public:
  220. //迭代器
  221. iterator begin()
  222. {
  223. //iterator it(head->next);
  224. //return it;
  225. //iterator是对ListIterator<T, T&, T*>的重命名
  226. //这里会返回一个ListIterator<T, T&, T*>类对象
  227. //head->next是传递给迭代器类对象构造函数的参数,调用iterator的构造函数
  228. return iterator(head->next);//构造匿名对象返回
  229. }
  230. iterator end()
  231. {
  232. return iterator(head);
  233. }
  234. //const类型迭代器
  235. const_iterator cbegin()const
  236. {
  237. return const_iterator(head->next);
  238. }
  239. const_iterator cend()const
  240. {
  241. return const_iterator(head);
  242. }
  243.  
  244. //反向迭代器
  245. //反向迭代器的成员变量是一个迭代器类对象
  246. //end()即为传递给反向迭代器类构造函数的参数
  247. reverse_iterator rbegin()
  248. {
  249. return reverse_iterator(end());
  250. }
  251. reverse_iterator rend()
  252. {
  253. return reverse_iterator(begin());
  254. }
  255. //反向const类型迭代器
  256. const_reverse_iteraotr crbegin()const
  257. {
  258. return const_reverse_iteraotr(cend());
  259. }
  260. const_reverse_iteraotr crend()const
  261. {
  262. return const_reverse_iteraotr(cbegin());
  263. }
  264.  
  265. /
  266. //容量
  267. size_t size()
  268. {
  269. auto it = cbegin();
  270. size_t count = 0;
  271. while (it != cend())
  272. {
  273. ++count;
  274. ++it;
  275. }
  276. return count;
  277. }
  278. bool empty()
  279. {
  280. return head->next == head;
  281. }
  282. void resize(int newsize,const T& value=T())
  283. {
  284. size_t oldsize = size();
  285. if (newsize > oldsize)
  286. {
  287. while (oldsize++<newsize)
  288. {
  289. push_back(value);
  290. }
  291. }
  292. if (newsize < oldsize)
  293. {
  294. while (oldsize-- < newsize)
  295. {
  296. pop_back();
  297. }
  298. }
  299. }
  300.  
  301. ///
  302. //元素访问
  303. T& front()
  304. {
  305. return *begin();
  306. }
  307. const T& front()const
  308. {
  309. return *cbegin();
  310. }
  311. T& back()
  312. {
  313. auto it = end();
  314. it--;
  315. return *it;
  316. }
  317. const T& back()const
  318. {
  319. auto it = end();
  320. it--;
  321. return *it;
  322. }
  323.  
  324.  
  325. /
  326. //元素修改
  327. void push_back(const T& value)
  328. {
  329. insert(end(), value);
  330. }
  331.  
  332. void pop_back()
  333. {
  334. if (empty())
  335. {
  336. return;
  337. }
  338. auto it = end();
  339. it--;
  340. erase(it);
  341. }
  342. void push_front(const T& value = T())
  343. {
  344. //Node* pos = head->next;
  345. /*Node* newnode = new Node(value);
  346. newnode->next = head->next;
  347. newnode->prev = head;
  348. head->next->prev = newnode;
  349. head->next = newnode;*/
  350. //复用insert
  351. insert(begin(), value);
  352. }
  353. void pop_front()
  354. {
  355. erase(begin());
  356. }
  357.  
  358. //?insert
  359. // iterator是ListIterator<T, T&, T*>
  360. iterator insert(iterator Insertpos, const T& value)
  361. {
  362. Node* newnode = new Node(value);
  363. Node* pos = Insertpos._pNode;//_pNode是节点类型的指针
  364. newnode->next = pos;
  365. newnode->prev = pos->prev;
  366. newnode->prev->next = newnode;
  367. pos->prev = newnode;
  368. //return newnode;
  369. //?迭代器是封装的Node*指针,此时不能再返回newnode
  370. return iterator(newnode);//构造匿名对象返回
  371. }
  372. //?erase
  373. iterator erase(iterator Erasepos)
  374. {
  375. Node* pos = Erasepos._pNode;
  376. Node* ret = pos->next;
  377. pos->prev->next = pos->next;
  378. pos->next->prev = pos->prev;
  379. delete pos;
  380. return iterator(ret);
  381. }
  382. iterator erase(iterator first, iterator last)
  383. {
  384. auto it = first;
  385. while (it != last)
  386. {
  387. //it=erase(it);
  388. erase(it++);
  389. }
  390. return it;
  391. }
  392.  
  393. void clear()
  394. {
  395. erase(begin(), end());
  396. }
  397. void swap(list<T>& l)
  398. {
  399. std::swap(head, l.head);
  400. }
  401.  
  402. private:
  403. //提供一个创造头结点的方法
  404. void CreatHead()
  405. {
  406. //调用节点类的构造方法
  407. head = new Node();
  408. head->next = head;
  409. head->prev = head;
  410. }
  411. private:
  412. Node* head;
  413.  
  414. };
  415.  
  416. template<class T>
  417. void PrintList(const list<T>& l)
  418. {
  419. auto it = l.cbegin();
  420. while (it != l.cend())
  421. {
  422. cout << *it << " ";
  423. ++it;
  424. }
  425. cout << endl;
  426. }
  427. }
  428.  
  429. void Test1()
  430. {
  431. ZH::list<int> l1;
  432. ZH::list<int> l2(3, 1);
  433. PrintList(l2);
  434. ZH::list<int> l3(l2.begin(), l2.end());
  435. PrintList(l3);
  436. vector<int> v{ 0,1,2,3,4 };
  437. ZH::list<int> l4(v.begin(), v.end());
  438. PrintList(l4);
  439. }
  440.  
  441. void Test2()
  442. {
  443. vector<int> v{ 1,2,3,4 };
  444. ZH::list<int> L1(v.begin(), v.end());
  445. L1.push_back(5);
  446. L1.push_back(6);
  447. L1.push_front(0);
  448. PrintList(L1);
  449. L1.pop_back();
  450. L1.pop_front();
  451. PrintList(L1);
  452. L1.erase(--L1.end());
  453. PrintList(L1);
  454. }
  455.  
  456. void Test3()
  457. {
  458. ZH::list<int> L1;
  459. L1.push_back(1);
  460. L1.push_back(2);
  461. L1.push_back(3);
  462. L1.push_front(0);
  463. PrintList(L1);
  464. L1.resize(6, 5);
  465. PrintList(L1);
  466. }
  467.  
  468. struct A
  469. {
  470. int a;
  471. int b;
  472. int c;
  473. };
  474.  
  475. void Test4()
  476. {
  477. A aa{ 1,2,3 };
  478. A bb{ 4,5,6 };
  479. A cc{ 7,8,9 };
  480. ZH::list<A> L;
  481. L.push_back(aa);
  482. L.push_back(bb);
  483. L.push_back(cc);
  484. auto it = L.begin();
  485. while (it != L.end())
  486. {
  487. //?it->得到的是节点的地址
  488. //本应是it->->a,编译器做了特殊处理
  489. cout << it->a << " ";
  490. it++;
  491. }
  492. cout << endl;
  493. }
  494.  
  495. void Test5()
  496. {
  497. ZH::list<int> L1;
  498. L1.push_back(0);
  499. L1.push_back(1);
  500. L1.push_back(2);
  501. L1.push_back(3);
  502. PrintList(L1);
  503. cout << L1.back() << endl;
  504. cout << L1.front() << endl;
  505. cout << L1.size() << endl;
  506. L1.clear();
  507. cout << L1.size() << endl;
  508. }
  509. void Test6()
  510. {
  511. ZH::list<int> L1;
  512. L1.push_back(0);
  513. L1.push_back(1);
  514. L1.push_back(2);
  515. L1.push_back(3);
  516. PrintList(L1);
  517. //区间删除
  518. /*L1.erase(L1.begin(), L1.end());
  519. PrintList(L1);*/
  520.  
  521. ZH::list<int> L2;
  522. L2.push_back(1);
  523. L2.push_back(2);
  524. L2.push_back(3);
  525. L2.push_back(4);
  526. L2.push_back(5);
  527. PrintList(L2);
  528. L1.swap(L2);
  529. PrintList(L1);
  530. PrintList(L2);
  531. }
  532.  
  533. int main()
  534. {
  535. Test6();
  536. system("pause");
  537. return 0;
  538. }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号