《数据结构与算法分析》书本代码,书本的代码内容居然分开超多部分,看起来真得很痛苦,之前看这一章老是看到这一部分就不想看,list的实现本来就麻烦,而且分开,所以一直都是跳开。不过通过认真分析,再敲代码,一边敲代码一边理解,收获真得很不错,而且这本书的习题很赞,有很多题都是要你在程序上完善,修改、添加。好了,体外话说完。

PS:这次加了两张图片!(《数据结构与算法分析》的图片,方便理解)。

PS:添加了习题3.15和3.16.

见:http://www.cnblogs.com/alan-forever/archive/2012/10/15/2725290.html

看了这些代码有数遍之后,觉得将const_iterator、iterator迭代器设置为公有嵌套类是很不错的。因为const_iterator、iterator迭代器,不同于Vector的迭代器,Vector的迭代器只是简单指针而这个List的迭代器的基本实现要比Vector的复杂。Vector原理是数组,数组本来就是指针,里面的元素储存在连续的地址里面,(++)(--)操作符不用重载就可以实现功能。而List不一样除了储存元素,它还有前指针、后指针,它是通过这些指针连接它之前及之后的Node(结点),因此List里面的元素在物理上是不连续的,所以要实现它的迭代器功能就需要定义一个类,并且重载操作符。(个人愚见)

  1 #include<iostream>
  2 using namespace std;
  3
  4 template <typename Object>
  5 class List
  6 {
  7 private:
  8     struct Node                                 //私有嵌套结构体。
  9     {
 10         Object data;
 11         Node *prev;
 12         Node *next;
 13
 14         Node( const Object & d = Object( ), Node *p = NULL, Node *n = NULL ) : data( d ), prev( p ), next( n ) { }
 15     };                                          /*Node结构体包含存储的项、指向Node之前及之后的指针和一个构造函数。都是公有的数据成员*/
 16 public:
 17     class const_iterator                        //公有嵌套类。
 18     {
 19     public:
 20         const_iterator( ) : current ( NULL ) { }     //const_iterator类的无参数构造函数。
 21
 22         const Object & operator* ( ) const
 23         {
 24             return retrieve( );
 25         }                                           //解引用操作符的重载。调用retrieve函数。
 26
 27         const_iterator & operator++ ( )
 28         {
 29             current = current->next;
 30             return *this;
 31         }
 32         //前自增操作符重载。当前的结点直接变成它指向的下一个结点,并返回。
 33         const_iterator operator++ ( int )
 34         {
 35             const_iterator old = *this;
 36             ++( *this );
 37             return old;
 38         }
 39         //后自增操作符重载。要先存储当前的结点,再调用前自增操作符,最后返回储存的结点。
 40         const_iterator operator-- ( )
 41         {
 42             current = current->prev;
 43             return *this;
 44         }
 45         //前自减操作符重载。当前的结点直接直接变成它指向的前一个结点,并返回。
 46         const_iterator operator-- ( int )
 47         {
 48             const_iterator old = *this;
 49             --( *this );
 50             return old;
 51         }
 52         //后自减操作符重载。先储存当前结点,再调用前自减操作符,最后返回储存的结点。
 53         const_iterator  operator+( int k ) const
 54         {
 55             const_iterator itr = *this;
 56             for( int i = 1; i <= k; ++i )
 57                 itr.current = itr.current->next;
 58             return itr;
 59         }
 60
 61         bool operator== ( const const_iterator & rhs ) const
 62         {
 63             return current == rhs.current;
 64         }
 65         bool operator != ( const const_iterator & rhs ) const
 66         {
 67             return !( *this == rhs );
 68         }
 69         //(==)(!=)操作符的重载。
 70     protected:
 71         Node *current;
 72
 73         Object & retrieve( ) const
 74         {
 75             return current->data;
 76         }                                       //返回当前结点储存的元素。
 77
 78         const_iterator( Node *p ) : current( p ) { }    //const_iterator的构造函数,储存当前结点
 79
 80         friend class List<Object>;              //友元函数,可以让List调用const_iterator的函数。
 81     };
 82
 83     class iterator//安装书本的代码,这个应该是const_iterator的派生类,因为很多操作都一样,但是老是报错,也只好这样写。
 84     {
 85     public:
 86         iterator( ) : current ( NULL ) { }
 87
 88         Object & operator* ( )
 89         {
 90             return retrieve( );
 91         }
 92
 93         iterator & operator++ ( )
 94         {
 95             current = current->next;
 96             return *this;
 97         }
 98
 99         iterator operator++ ( int )
100         {
101             iterator old = *this;
102             ++( *this );
103             return old;
104         }
105         iterator operator-- ( )
106         {
107             current = current->prev;
108             return *this;
109         }
110         iterator operator-- ( int )
111         {
112             iterator old = *this;
113             --( *this );
114             return old;
115         }
116
117         iterator  operator+( int k )
118         {
119             iterator itr = *this;
120             for( int i = 1; i <= k; ++i )
121                 itr.current = itr.current->next;
122             return itr;
123         }
124
125
126         bool operator== ( const iterator & rhs ) const
127         {
128             return current == rhs.current;
129         }
130         bool operator != ( const iterator & rhs ) const
131         {
132             return !( *this == rhs );
133         }
134
135     protected:
136         Node *current;
137
138         Object & retrieve( ) const
139         {
140             return current->data;
141         }
142
143         iterator( Node *p ) : current( p ) { }
144
145         friend class List<Object>;
146     };
147
148     class const_reverse_iterator
149     {
150     public:
151         const_reverse_iterator( ) : current( NULL ) { }
152
153         const Object & operator* ( ) const
154         {
155             return retrieve( );
156         }
157
158         const_reverse_iterator & operator++ ( )
159         {
160             current = current->prev;
161             return * this;
162         }
163
164         const_reverse_iterator  operator++ ( int )
165         {
166             const_reverse_iterator old = *this;
167             ++( *this );
168             return old;
169         }
170
171         const_reverse_iterator & operator--  ( )
172         {
173             current = current->next;
174             return * this;
175         }
176
177         const_reverse_iterator  operator-- ( int )
178         {
179             const_reverse_iterator old = *this;
180             ++( *this );
181             return old;
182         }
183
184         bool operator== ( const const_reverse_iterator & rhs ) const
185         {
186             return current == rhs.current;
187         }
188
189         bool operator!= ( const const_reverse_iterator & rhs ) const
190         {
191             return !( *this == rhs );
192         }
193
194     private:
195         Node * current;
196
197         Object & retrieve( ) const
198         {
199             return current->data;
200         }
201
202         const_reverse_iterator( Node * p ) : current( p ) { }
203
204         friend class List<Object>;
205     };
206     //逆向迭代器
207
208     class reverse_iterator
209     {
210     public:
211         reverse_iterator( ) : current( NULL ) { }
212
213         const Object & operator* ( ) const
214         {
215             return retrieve( );
216         }
217
218         reverse_iterator & operator++ ( )
219         {
220             current = current->prev;
221             return * this;
222         }
223
224         reverse_iterator  operator++ ( int )
225         {
226             reverse_iterator old = *this;
227             ++( *this );
228             return old;
229         }
230
231         const_reverse_iterator & operator--  ( )
232         {
233             current = current->next;
234             return * this;
235         }
236
237         reverse_iterator  operator-- ( int )
238         {
239             const_reverse_iterator old = *this;
240             --( *this );
241             return old;
242         }
243
244         bool operator== ( const reverse_iterator & rhs ) const
245         {
246             return current == rhs.current;
247         }
248
249         bool operator!= ( const reverse_iterator & rhs ) const
250         {
251             return !( *this == rhs );
252         }
253
254     private:
255         Node * current;
256
257         Object & retrieve( ) const
258         {
259             return current->data;
260         }
261
262         reverse_iterator( Node * p ) : current( p ) { }
263
264         friend class List<Object>;
265     };
266     //逆向迭代器
267
268 public:
269     List()
270     {
271         init( );
272     }
273     //List的构造函数,调用私有成员函数init。生成一个默认链表(有表头、表尾结点的链表)。
274     ~List()
275     {
276         clear();
277         delete head;
278         delete tail;
279     }
280     //析构函数,要将里面都东西删除了。
281     List( const List & rhs)
282     {
283         init( );
284         *this = rhs;
285     }
286     //复制构造函数。
287     const List & operator= ( const List & rhs)
288     {
289         if( this == &rhs)
290             return *this;
291         clear();
292         for( const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)
293             push_back( *itr );
294         return *this;
295     }
296     //(=)操作符重载。
297     iterator begin( )
298     {
299         return iterator( head->next );
300     }
301     const_iterator begin( ) const
302     {
303         return const_iterator( head->next );
304     }                                           //begin迭代器。不是返回head。head只是表头,不是储存第一个元素的结点。
305     iterator end( )
306     {
307         return iterator( tail );
308     }
309     const_iterator end( ) const
310     {
311         return const_iterator( tail );
312     }
313     //end迭代器。返回tail,因为它一定是储存最后一个元素的结点的后一个。
314
315     reverse_iterator rbegin( )
316     {
317         return reverse_iterator( tail->prev );
318     }
319     const_reverse_iterator rbegin( ) const
320     {
321         return const_reverse_iterator( tail->prev );
322     }
323     //逆向begin迭代器,返回tail的前一个迭代器。
324
325     reverse_iterator rend( )
326     {
327         return reverse_iterator( head );
328     }
329     const_reverse_iterator rend( ) const
330     {
331         return const_reverse_iterator( head );
332     }
333     //逆向end迭代器,返回head节点的迭代器。
334
335     int size( )
336     {
337         return theSize;
338     }                                           //返回链表的大小。
339     bool empty( )
340     {
341         return size( ) == 0;
342     }
343
344     void clear( )
345     {
346         while( !empty( ) )
347             pop_front( );
348     }
349     //将链表清空。
350     Object & front( )
351     {
352         return *begin( );
353     }
354     const Object & front( ) const
355     {
356         return *begin( );
357     }
358     //返回第一个元素,即返回begin迭代器指向的元素。调用iterator的(*)操作符。
359     Object & back( )
360     {
361         return *--end( );
362     }
363     const Object & back( ) const
364     {
365         return *--end( );
366     }
367     //返回最后一个元素,即返回end迭代器的前一个结点的元素。
368     void push_front( const Object & x)
369     {
370         insert( begin( ), x );
371     }
372     //头插入!调用insert函数,在第一个元素前插入新的元素。
373     void push_back( const Object & x )
374     {
375         insert( end( ), x );
376     }
377     //尾插入!调用insert函数,在表尾结点前插入新的元素,相当于插在最后一个元素的后面。
378     void pop_front( )
379     {
380         erase( begin( ) );
381     }
382     //删除第一个元素,调用erase函数。
383     void pop_back( )
384     {
385         erase( --end( ) );
386     }
387     //删除最后一个函数。所以end迭代器返回的迭代器要自减才是最后一个函数。
388     iterator insert( iterator itr, const Object & x )
389     {
390         Node *p = itr.current;
391         theSize++;
392         return iterator( p->prev = p->prev->next = new Node( x, p->prev, p ) );
393     }
394     //将新的结点插入指定的迭代器的前面。见图二。
395     iterator erase ( iterator itr)
396     {
397         Node *p = itr.current;
398         iterator retVal( p->next );
399         p->prev->next = p->next;
400         p->next->prev = p->prev;
401         delete p;
402         theSize--;
403
404         return retVal;
405     }                                           //删除迭代器指向的结点,并返回一个迭代器,指向被删除元素后面的元素。
406     iterator erase ( iterator start, iterator end )
407     {
408         for( iterator itr = start; itr != end; )
409             itr = erase( itr );
410
411         return end;
412     }
413
414     //删除迭代器start和end所标记的范围所有元素,返回一个迭代器,指向被删除元素段后面的元素。
415
416     void splice( iterator position, List<Object> & lst )
417     {
418         Node *p = position.current;
419
420         p->prev->next = lst.head->next;
421         lst.head->next->prev = p->prev;
422         lst.tail->prev->next = p;
423         p->prev = lst.tail->prev;
424
425         theSize += lst.size();
426
427         lst.init();
428     }
429
430     friend iterator find(iterator start, iterator end, const Object & x )
431     {
432         iterator itr = start;
433         while( itr != end && *itr != x )
434         {
435             ++itr;
436         }
437         return itr;
438     }
439
440 private:
441     int theSize;                                //链表的大小
442     Node *head;                                 //表头结点
443     Node *tail;                                 //表尾结点
444
445     void init()
446     {
447         theSize = 0;
448         head = new Node;
449         tail = new Node;
450         head->next = tail;
451         tail->prev = head;
452     }                                           //init函数,初始化链表。见图一
453 };
454
455
456 int main( )
457 {
458     List<int> l1;
459     List<int> l2;
460     int num, m;
461     cout << "l1的元素数量:" << endl;
462     cout << l1.size() << endl;
463     if( l2.empty() )
464         cout << "l2为空的!" << endl;
465     else
466         cout << "l2不是空的!" << endl;
467     cout << "输入你想插入链表的元素个数:" << endl;
468     cin >> num;
469     for(int i = 1; i <= num; ++i)
470     {
471         cin >> m;
472         l1.push_back(m);
473         l2.push_front(m);
474     }
475
476     /*List<int>::iterator itr1 = l1.begin();
477     List<int>::iterator itr = itr1 + 5;
478     cout << *itr << endl;*/
479     //3.14
480
481     /*List<int>::iterator itr1 = l1.begin();
482     List<int>::iterator itr2 = --l2.end();
483     List<int>::iterator itr = find( itr1, itr2, 20);
484     cout << *itr << endl;*/
485     //3.3
486
487     /*List<int>::reverse_iterator itr1 = l1.rbegin();
488     while( itr1 != l1.rend() )
489         cout << *itr1++ <<" ";
490     cout << endl;*/
491     //3.16
492
493     /*List<int>::iterator pos = l1.begin();
494     l1.splice( pos, l2 );
495
496     for(List<int>::iterator itr = l1.begin(); itr != l1.end(); ++itr)
497         cout << *itr << " ";
498     cout << endl;*/
499     //3.15
500
501     cout << "l1的元素数量:" << endl;
502     cout << l1.size() << endl;
503     cout << "l2的元素数量:" << endl;
504     cout << l2.size() << endl;
505     cout << "l1是尾插入,l2是头插入!!!!" << endl;
506     cout << "l1的全部元素顺序输出:" << endl;
507     for(List<int>::iterator itr = l1.begin(); itr != l1.end(); ++itr)
508         cout << *itr << " ";
509     cout << endl;
510     cout << "l2的全部元素顺序输出:" << endl;
511     for(List<int>::iterator itr = l2.begin(); itr != l2.end(); ++itr)
512         cout << *itr << " ";
513     cout << endl;
514     cout << "l1的第一个元素: " <<l1.front() << endl;
515     cout << "l1的最后一个元素: " <<l1.back() << endl;
516     cout << "l2的第一个元素: " <<l2.front() << endl;
517     cout << "l2的最后一个元素: " <<l2.back() << endl;
518     List<int> l3(l1);
519     cout << "l3为调用复制构造函数!" << endl;
520     cout << "l3中元素的数目:" << endl;
521     cout << l3.size() << endl;
522     cout << "输出l3的全部元素!(与l1的全部元素比较,同一个位置上的元素是一样!)" << endl;
523     for(List<int>::iterator itr = l3.begin(); itr != l3.end(); ++itr)
524         cout << *itr << " ";
525     cout << endl;
526     List<int>::iterator itr1 = l3.begin();
527     l3.erase( itr1 );
528     cout << "对l3调用erase函数,删除begin迭代器所知指向的元素!" << endl;
529     cout << "输出l3中元素的数数目:" << endl;
530     cout << l3.size() << endl;
531     cout << "输出l3的全部元素:" << endl;
532     for(List<int>::iterator itr = l3.begin(); itr != l3.end(); ++itr)
533         cout << *itr << " ";
534     cout << endl;
535     List<int>::iterator itr2 = l3.begin();
536     List<int>::iterator itr3 = l3.end();
537     l3.erase( itr2, itr3);
538     cout << "对l3调用erase函数,删除迭代器begin和end之间的全部元素!" << endl;
539     cout << "输出l3重元素的数目!" << endl;
540     cout << l3.size() << endl;
541     return 0;
542 }

转载于:https://www.cnblogs.com/alan-forever/archive/2012/09/12/2682437.html

STL之list学习(2)(list代码实现)(只剩最后一步,迭代器升级!!)相关推荐

  1. STL源码学习之空间配置

    STL的空间配置器主要用于内存的分配.填充.释放等操作,在学习它之前,需要深入一点理解new和delete.由于new和delete分两段操作:内存配置和对象构建(析构),本文亦将按此进行分类,其中第 ...

  2. STL快速入门学习教程之map的简单使用

    STL快速入门学习教程之map的简单使用 map是STL中的一个关联容器,它以一对一的数据进行整理(第一个数值称为关键字,且这个关键字只能在map中出现一次,第二个数值称为前关键字的值),正是由于这种 ...

  3. STL源码学习(2)-迭代器概念与traits编程技法

    文章首发于:My Blog 欢迎大佬们前来逛逛 文章目录 1. 迭代器设计思维 1.2 迭代器的相应型别 1.3 Traits编程技巧 1.3.1 value_type 1.3.2 deference ...

  4. java编程石头剪刀布图片_石头、剪刀、布!10分钟带你打开深度学习大门,代码已开源...

    原标题:石头.剪刀.布!10分钟带你打开深度学习大门,代码已开源 沉沉 发自 宇宙中心 量子位 出品 | 公众号 QbitAI 深度学习技术的不断普及,越来越多的语言可以用来进行深度学习项目的开发,即 ...

  5. Python编程语言学习:两行代码输出根目录下所有子文件夹的绝对路径、相对路径

    Python编程语言学习:两行代码输出根目录下所有子文件夹的绝对路径.相对路径 目录 两行代码输出根目录下所有子文件夹的绝对路径.相对路径 两行代码输出根目录下所有子文件夹的绝对路径.相对路径 #Py ...

  6. 循环神经网络matlab程序设计,神经网络及深度学习(包含matlab代码).pdf

    神经网络及深度学习(包含matlab代码) 神经网络及深度学习 (包含 MATLAB 仿真) 人工神经网络(Artificial Neural Network,即 ANN ), 作为对人脑最简单的一种 ...

  7. java学习教程之代码块

    学编程吧java学习教程之代码块发布了,欢迎通过xuebiancheng8.com来访问 java中的代码块包括下面几种: 1.普通代码块 2.构造代码块 3.静态代码块 1.普通代码块很简单看下面这 ...

  8. NGenerics算法库是学习的好代码

    NGenerics算法库是学习的好代码 地址为: http://www.codeplex.com/NGenerics posted on 2007-04-29 22:48 黄尚 阅读(...) 评论( ...

  9. 从零开始编写深度学习库(四)Eigen::Tensor学习使用及代码重构

    从零开始编写深度学习库(四)Eigen::Tensor学习使用及代码重构 博客:http://blog.csdn.net/hjimce 微博:黄锦池-hjimce   qq:1393852684 一. ...

最新文章

  1. 监听发现局域网dropbox客户端broadcast-dropbox-listener
  2. 数据库的定义、关系型数据库的四种约束。。
  3. xamarin.android蓝牙,在Android上连接Xamarin的配对蓝牙设备
  4. 前端学习(2223):react之jsx的样式和注释(2)
  5. 火币辟谣:警惕假冒火币生态链网站
  6. 【报告分享】中国“新基建”发展研究报告.pdf(附下载链接)
  7. 敏捷 - #7 原则:工作软件是进度的主要衡量标准 ( #7 Agile - Principle)
  8. flex blazeds java spring_flex+blazeds+java+spring后台消息推送
  9. 装系统提示缺少计算机所需的介质驱动程序,win8系统UEFi安装提示“缺少计算机所需的介质驱动程序”的图文步骤...
  10. 洞态IAST Agent正式开源
  11. poc, vul, exp都是什么意思呢?
  12. Linux TF卡ext4文件系统录制视频文件用拷贝不用移动的影响
  13. 三森すずこさん コール・曲色 '17.04
  14. html5 设备管理信息 device
  15. alert angularjs
  16. cmd中怎么打开计算机,如何打开命令行窗口?电脑打开cmd命令行窗口5大方法详解...
  17. BottomSheetDialog禁止下滑关闭
  18. 【Java 数据结构 算法】宁可累死自己, 也要卷死别人 18 贪心算法
  19. html谷歌兼容代码,让网站变灰的css代码(支持IE、Firefox和Chrome)
  20. 三星手机直连电脑Samsung Flow

热门文章

  1. 全局变量、成员变量、类变量、静态变量、实例变量、局部变量的定义与区别
  2. SpringBoot 嵌入式Servlet容器
  3. 数据导出到Excel
  4. C++ 双向链表的建立与遍历
  5. STM32开发 -- patch生成和使用
  6. 汇编语言LAHF和SAHF指令
  7. Google Archive Patch 源码解析
  8. 简单支付验证(SPV)与创新
  9. ICLR 2017 | GAN Missing Modes 和 GAN
  10. 玩游戏计算机缺失msvcp140,玩英雄联盟提示电脑缺少msvcp140.dll怎么办