数据结构基础(10) --单链表迭代器的设计与实现

为了向 STL 致敬(O(∩_∩)O~), 我们模仿STL中的list的迭代器, 我们也自己实现一个MyList的迭代器, 以供遍历整个链表的所有元素:

首先:Node节点需要做如下修改(注意后缀有+的代码)

  1. //链表节点  
  2. template <typename Type>  
  3. class Node  
  4. {  
  5.     friend class MyList<Type>;  
  6.     friend class ListIterator<Type>;  //+  
  7.   
  8.     template <typename T>  
  9.     friend ostream &operator<<(ostream &os, const MyList<T> &list);  
  10. private:  
  11.     Node(const Type &dataValue):data(dataValue), next(NULL) {}  
  12.   
  13.     Type data;  //数据域:节点数据  
  14.     Node *next; //指针域:下一个节点  
  15. };  

然后:MyList类同样也需要做修改,但是由于MyList类过长修改之处也较少因此在此就不贴出完整代码会附到博客最后

 

ListIterator的设计

  1. template <typename Type>  
  2. class ListIterator  
  3. {  
  4. public:  
  5.     ListIterator(const MyList<Type> &_list):  
  6.         list(_list),  
  7.         currentNode((_list.first)->next) {}  
  8.   
  9.     //重载 *operator  
  10.     const Type &operator*() const throw (std::out_of_range);  
  11.     Type &operator*() throw (std::out_of_range);  
  12.   
  13.     //重载 ->operator  
  14.     const Node<Type> *operator->() const throw (std::out_of_range);  
  15.     Node<Type> *operator->() throw (std::out_of_range);  
  16.   
  17.     //重载 ++operator  
  18.     ListIterator &operator++() throw (std::out_of_range);  
  19.     //注意:此处返回的是值,而不是reference  
  20.     ListIterator operator++(intthrow (std::out_of_range);  
  21.   
  22.     bool isEmpty() const;  
  23.   
  24. private:  
  25.     const MyList<Type> &list;  
  26.     Node<Type> *currentNode;  
  27. };  

ListIterator类的实现

  1. template <typename Type>  
  2. const Type &ListIterator<Type>::operator*() const  
  3. throw (std::out_of_range)  
  4. {  
  5.     if (isEmpty())  
  6.         throw std::out_of_range("iterator is out of range");  
  7.     // 返回当前指针指向的内容  
  8.     return currentNode->data;  
  9. }  
  10.   
  11. template <typename Type>  
  12. Type &ListIterator<Type>::operator*()  
  13. throw (std::out_of_range)  
  14. {  
  15.     //首先为*this添加const属性,  
  16.     //以调用该函数的const版本,  
  17.     //然后再使用const_case,  
  18.     //将该函数调用所带有的const属性转除  
  19.     //operator->()的non-const版本与此类同  
  20.     return  
  21.         const_cast<Type &>(  
  22.             static_cast<const ListIterator<Type> &>(*this).operator*()  
  23.         );  
  24. }  

  1. template <typename Type>  
  2. const Node<Type> *ListIterator<Type>::operator->() const  
  3. throw (std::out_of_range)  
  4. {  
  5.     if (isEmpty())  
  6.         throw std::out_of_range("iterator is out of range");  
  7.     //直接返回指针  
  8.     return currentNode;  
  9. }  
  10.   
  11. template <typename Type>  
  12. Node<Type> *ListIterator<Type>::operator->()  
  13. throw (std::out_of_range)  
  14. {  
  15.     // 见上  
  16.     return  
  17.         const_cast<Node<Type> *> (  
  18.             static_cast<const ListIterator<Type> >(*this).operator->()  
  19.         );  
  20. }  

  1. template <typename Type>  
  2. ListIterator<Type> &ListIterator<Type>::operator++()  
  3. throw (std::out_of_range)  
  4. {  
  5.     if (isEmpty())  
  6.         throw std::out_of_range("iterator is out of range");  
  7.     //指针后移  
  8.     currentNode = currentNode->next;  
  9.     return *this;  
  10. }  
  11. template <typename Type>  
  12. ListIterator<Type> ListIterator<Type>::operator++(int)  
  13. throw (std::out_of_range)  
  14. {  
  15.     ListIterator tmp(*this);  
  16.     ++ (*this); //调用前向++版本  
  17.   
  18.     return tmp;  
  19. }  

  1. //判空  
  2. template <typename Type>  
  3. bool ListIterator<Type>::isEmpty() const  
  4. {  
  5.     if (currentNode == NULL)  
  6.         return true;  
  7.     return false;  
  8. }  

-ListIterator测试代码:

  1. int main()  
  2. {  
  3.     std::list<int> iStdList;  
  4.     MyList<int>    iMyList;  
  5.     for (int i = 0; i < 10; ++i)  
  6.     {  
  7.         iStdList.push_back(i+1);  
  8.         iMyList.insert(i+1, i+1);  
  9.     }  
  10.   
  11.     for (std::list<int>::iterator iter = iStdList.begin();  
  12.             iter != iStdList.end();  
  13.             ++ iter)  
  14.     {  
  15.         cout << *iter << ' ';  
  16.     }  
  17.     cout << endl;  
  18.   
  19.     for (ListIterator<int> iter(iMyList);  
  20.             !iter.isEmpty();  
  21.             ++ iter)  
  22.     {  
  23.         cout << *iter << ' ';  
  24.     }  
  25.     cout << endl;  
  26.   
  27.     cout << "Test: \n\t" << iMyList << endl;  
  28.   
  29.   
  30.     ListIterator<int> iter(iMyList);  
  31. cout << "first = " << *iter << endl;  
  32. }  


附-MyList完整源代码

  1. //MyList.h  
  2. #ifndef MYLIST_H_INCLUDED  
  3. #define MYLIST_H_INCLUDED  
  4.   
  5. #include <iostream>  
  6. #include <stdexcept>  
  7. using namespace std;  
  8.   
  9. //前向声明  
  10. template <typename Type>  
  11. class MyList;  
  12. template <typename Type>  
  13. class ListIterator;  
  14.   
  15. //链表节点  
  16. template <typename Type>  
  17. class Node  
  18. {  
  19.     //可以将MyList类作为Node的友元  
  20.     //同时也可以将Node类做成MyList的嵌套类, 嵌套在MyList中, 也可以完成该功能  
  21.     friend class MyList<Type>;  
  22.     friend class ListIterator<Type>;  
  23.   
  24.     template <typename T>  
  25.     friend ostream &operator<<(ostream &os, const MyList<T> &list);  
  26. private:  
  27.     //constructor说明:  
  28.     //next = NULL;    //因为这是一个新生成的节点, 因此下一个节点为空  
  29.     Node(const Type &dataValue):data(dataValue), next(NULL) {}  
  30.   
  31.     Type data;  //数据域:节点数据  
  32.     Node *next; //指针域:下一个节点  
  33. };  
  34.   
  35. //链表  
  36. template <typename Type>  
  37. class MyList  
  38. {  
  39.     template <typename T>  
  40.     friend ostream &operator<<(ostream &os, const MyList<T> &list);  
  41.   
  42.     friend class ListIterator<Type>;  
  43. public:  
  44.     MyList();  
  45.     ~MyList();  
  46.   
  47.     //将元素插入表头  
  48.     void insertFront(const Type &data);  
  49.     //将元素插入到位置index上(index从1开始)  
  50.     void insert(const Type &data, int index);  
  51.     //删除表中所有值为data的节点  
  52.     void remove(const Type &data);  
  53.     bool isEmpty() const;  
  54.   
  55.     //链表反转  
  56.     void invort();  
  57.     //将链表(list)链接到本条链表的末尾  
  58.     void concatenate(const MyList<Type> &list);  
  59.   
  60. private:  
  61.     //指向第一个节点的指针  
  62.     Node<Type> *first;  
  63. };  
  64.   
  65. template <typename Type>  
  66. MyList<Type>::MyList()  
  67. {  
  68.     //first指向一个空节点  
  69.     first = new Node<Type>(0);  
  70.     first -> next = NULL;  
  71. }  
  72. template <typename Type>  
  73. MyList<Type>::~MyList()  
  74. {  
  75.     Node<Type> *deleteNode = NULL;  
  76.     while (first != NULL)  
  77.     {  
  78.         deleteNode = first;  
  79.         first = first -> next;  
  80.         delete deleteNode;  
  81.     }  
  82. }  
  83.   
  84. template <typename Type>  
  85. void MyList<Type>::insertFront(const Type &data)  
  86. {  
  87.     Node<Type> *newNode = new Node<Type>(data);  
  88.     newNode -> next = first -> next;  
  89.     first -> next = newNode;  
  90. }  
  91.   
  92. template <typename Type>  
  93. void MyList<Type>::insert(const Type &data, int index)  
  94. {  
  95.     //由于我们在表头添加了一个空节点  
  96.     //因此如果链表为空, 或者在链表为1的位置添加元素  
  97.     //其操作与在其他位置添加元素相同  
  98.   
  99.     int count = 1;  
  100.     //此时searchNode肯定不为NULL  
  101.     Node<Type> *searchNode = first;  
  102.     // 找到要插入的位置  
  103.     // 如果所给index过大(超过了链表的长度)  
  104.     // 则将该元素插入到链表表尾  
  105.     // 原因是 searchNode->next != NULL 这个条件已经不满足了  
  106.     // 已经到达表尾  
  107.     while (count < index && searchNode->next != NULL)  
  108.     {  
  109.         ++ count;  
  110.         searchNode = searchNode->next;  
  111.     }  
  112.   
  113.     // 插入链表  
  114.     Node<Type> *newNode = new Node<Type>(data);  
  115.     newNode->next = searchNode->next;  
  116.     searchNode->next = newNode;  
  117. }  
  118.   
  119. template <typename Type>  
  120. void MyList<Type>::remove(const Type &data)  
  121. {  
  122.     if (isEmpty())  
  123.         return ;  
  124.   
  125.     Node<Type> *previous = first;   //保存要删除节点的前一个节点  
  126.     for (Node<Type> *searchNode = first->next;  
  127.             searchNode != NULL;  
  128.             searchNode = searchNode->next)  
  129.     {  
  130.         if (searchNode->data == data)  
  131.         {  
  132.             previous->next = searchNode->next;  
  133.             delete searchNode;  
  134.             //重新调整searchNode指针  
  135.             //继续遍历链表查看是否还有相等元素  
  136.   
  137.             //如果当前searchNode已经到达了最后一个节点  
  138.             //也就是searchNode->next已经等于NULL了, 则下面这条语句不能执行  
  139.             if (previous->next == NULL)  
  140.                 break;  
  141.   
  142.             searchNode = previous->next;  
  143.         }  
  144.         previous = searchNode;  
  145.     }  
  146. }  
  147. template <typename Type>  
  148. bool MyList<Type>::isEmpty() const  
  149. {  
  150.     return first->next == NULL;  
  151. }  
  152.   
  153. template <typename Type>  
  154. void MyList<Type>::concatenate(const MyList<Type> &list)  
  155. {  
  156.     if (isEmpty())//如果自己的链表为空  
  157.     {  
  158.         first = list.first;  
  159.         return ;  
  160.     }  
  161.     else if (list.isEmpty())    //如果第二条链表为空  
  162.     {  
  163.         return ;  
  164.     }  
  165.   
  166.     Node<Type> *endNode = first->next;  
  167.     //找到第一条链表的末尾节点  
  168.     while (endNode->next != NULL)  
  169.     {  
  170.         endNode = endNode->next;  
  171.     }  
  172.   
  173.     //找到第二条链表的第一个真实元素  
  174.     Node<Type> *secondListNode = (list.first)->next;  
  175.     //注意: 需要将第二个链表中的元素值copy出来  
  176.     //不能直接将第二条链表的表头链接到第一条链表的表尾  
  177.     //不然在析构函数回收内存时会发生错误(即:同一段内存释放两次)  
  178.     while (secondListNode != NULL)  
  179.     {  
  180.         Node<Type> *newNode = new Node<Type>(secondListNode->data);  
  181.         newNode->next = NULL;  
  182.         endNode->next = newNode;  
  183.   
  184.         //两条链表同时前进  
  185.         endNode = endNode->next;  
  186.         secondListNode = secondListNode->next;  
  187.     }  
  188. }  
  189.   
  190. template <typename Type>  
  191. void MyList<Type>::invort()  
  192. {  
  193.     if (!isEmpty())  
  194.     {  
  195.         //p指向正向链表的第一个真实节点  
  196.         //随后, p也会沿正方向遍历到链表末尾  
  197.         Node<Type> *p = first->next;  
  198.   
  199.         //q会成为倒向的第一个真实节点  
  200.         //首先将q设置为NULL: 保证反向之后  
  201.         //最后一个元素的指针域指向NULL, 以表示链表结束  
  202.         Node<Type> *q = NULL;  
  203.         while (p != NULL)  
  204.         {  
  205.             Node<Type> *r = q;  //暂存q当前指向的节点  
  206.             //q后退(沿着正向后退)  
  207.             q = p;  
  208.             //p前进(沿着正向前进), 保证p能够始终领先q一个位置  
  209.             p = p -> next;  
  210.             //将指针逆向反转  
  211.             //注意:一点要保证这条语句在p指针移动之后运行,  
  212.             //不然p就走不了了...(因为q改变了指针的朝向)  
  213.             q -> next = r;  
  214.         }  
  215.   
  216.         //此时q成为反向链表的第一个真实元素  
  217.         //但是为了维护像以前一样的first指针指向一个无用的节点(以使前面的操作不会出错)  
  218.         //于是我们需要将first的指针域指向q  
  219.         first->next = q;  
  220.     }  
  221. }  
  222.   
  223. //显示链表中的所有数据(测试用)  
  224. template <typename Type>  
  225. ostream &operator<<(ostream &os, const MyList<Type> &list)  
  226. {  
  227.     for (Node<Type> *searchNode = list.first -> next;  
  228.             searchNode != NULL;  
  229.             searchNode = searchNode -> next)  
  230.     {  
  231.         os << searchNode -> data;  
  232.         if (searchNode -> next != NULL) //尚未达到链表的结尾  
  233.             cout << " -> ";  
  234.     }  
  235.   
  236.     return os;  
  237. }  
  238.   
  239. //ListIterator的设计与实现  
  240. template <typename Type>  
  241. class ListIterator  
  242. {  
  243. public:  
  244.     ListIterator(const MyList<Type> &_list):  
  245.         list(_list),  
  246.         currentNode((_list.first)->next) {}  
  247.   
  248.     //重载 *operator  
  249.     const Type &operator*() const throw (std::out_of_range);  
  250.     Type &operator*() throw (std::out_of_range);  
  251.   
  252.     //重载 ->operator  
  253.     const Node<Type> *operator->() const throw (std::out_of_range);  
  254.     Node<Type> *operator->() throw (std::out_of_range);  
  255.   
  256.     //重载 ++operator  
  257.     ListIterator &operator++() throw (std::out_of_range);  
  258.     //注意:此处返回的是值,而不是reference  
  259.     ListIterator operator++(intthrow (std::out_of_range);  
  260.   
  261.     bool isEmpty() const;  
  262.   
  263. private:  
  264.     const MyList<Type> &list;  
  265.     Node<Type> *currentNode;  
  266. };  
  267.   
  268. template <typename Type>  
  269. const Type &ListIterator<Type>::operator*() const  
  270. throw (std::out_of_range)  
  271. {  
  272.     if (isEmpty())  
  273.         throw std::out_of_range("iterator is out of range");  
  274.     // 返回当前指针指向的内容  
  275.     return currentNode->data;  
  276. }  
  277. template <typename Type>  
  278. Type &ListIterator<Type>::operator*()  
  279. throw (std::out_of_range)  
  280. {  
  281.     //首先为*this添加const属性,  
  282.     //以调用该函数的const版本,  
  283.     //然后再使用const_case,  
  284.     //将该函数调用所带有的const属性转除  
  285.     //operator->()的non-const版本与此类同  
  286.     return  
  287.         const_cast<Type &>(  
  288.             static_cast<const ListIterator<Type> &>(*this).operator*()  
  289.         );  
  290. }  
  291.   
  292. template <typename Type>  
  293. const Node<Type> *ListIterator<Type>::operator->() const  
  294. throw (std::out_of_range)  
  295. {  
  296.     if (isEmpty())  
  297.         throw std::out_of_range("iterator is out of range");  
  298.     //直接返回指针  
  299.     return currentNode;  
  300. }  
  301.   
  302. template <typename Type>  
  303. Node<Type> *ListIterator<Type>::operator->()  
  304. throw (std::out_of_range)  
  305. {  
  306.     // 见上  
  307.     return  
  308.         const_cast<Node<Type> *> (  
  309.             static_cast<const ListIterator<Type> >(*this).operator->()  
  310.         );  
  311. }  
  312.   
  313. template <typename Type>  
  314. ListIterator<Type> &ListIterator<Type>::operator++()  
  315. throw (std::out_of_range)  
  316. {  
  317.     if (isEmpty())  
  318.         throw std::out_of_range("iterator is out of range");  
  319.     //指针前移  
  320.     currentNode = currentNode->next;  
  321.     return *this;  
  322. }  
  323. template <typename Type>  
  324. ListIterator<Type> ListIterator<Type>::operator++(int)  
  325. throw (std::out_of_range)  
  326. {  
  327.     ListIterator tmp(*this);  
  328.     ++ (*this); //调用前向++版本  
  329.   
  330.     return tmp;  
  331. }  
  332. template <typename Type>  
  333. bool ListIterator<Type>::isEmpty() const  
  334. {  
  335.     if (currentNode == NULL)  
  336.         return true;  
  337.     return false;  
  338. }  
  339.   
  340. #endif // MYLIST_H_INCLUDED 


原文地址:http://blog.csdn.net/zjf280441589/article/details/42430329

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值