zoukankan      html  css  js  c++  java
  • Iterator 迭代器

    意图

    提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。

    动机

    一个聚合对象, 如列表(list), 应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构

    迭代器类定义了一个访问该列表元素的接口。迭代器对象负责跟踪当前的元素 ;即, 它知道哪些元素已经遍历过了。

    适用性

    • 访问一个聚合对象的内容而无需暴露它的内部表示。
    • 支持对聚合对象的多种遍历。
    • 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)。

    结构

    定义一个抽象列表类AbstractList,它提供操作列表的公共接口。类似地,我们也需要一个抽象的迭代器类Iterator,它定义公共的迭代接口。然后我们可以为每个不同的列表实现定义具体的Iterator子类。这样迭代机制就与具体的聚合类无关了。

    参与者

    Iterator:迭代器定义访问和遍历元素的接口。

    ConcreteIterator:具体迭代器实现迭代器接口;对该聚合遍历时跟踪当前位置。

    Aggregate:聚合定义创建相应迭代器对象的接口。

    ConcreteAggregate:具体聚合实现创建相应迭代器的接口,该操作返回ConcreteAggregate的一个适当的实例。

    效果

    • 访问一个聚合对象的内容而无需暴露它的内部表示;
    • 支持对聚合对象的多种遍历(从前到后,从后到前);
    • 为遍历不同的聚合结构提供一个统一的接口,即支持多态迭代。

    实现

      1 #include <iostream>
      2 using namespace std;
      3 
      4 typedef struct tagNode
      5 {
      6     int value;
      7     tagNode *pNext;
      8 }Node;
      9 
     10 class JTList
     11 {
     12 public:
     13     JTList() : m_pHead(NULL), m_pTail(NULL){};
     14     JTList(const JTList &);
     15     ~JTList();
     16     JTList &operator=(const JTList &);
     17 
     18     long GetCount() const;
     19     Node *Get(const long index) const;
     20     Node *First() const;
     21     Node *Last() const;
     22     bool Includes(const int &) const;
     23 
     24     void Append(const int &);
     25     void Remove(Node *pNode);
     26     void RemoveAll();
     27 
     28 private:
     29     Node *m_pHead;
     30     Node *m_pTail;
     31     long m_lCount;
     32 };
     33 
     34 class Iterator
     35 {
     36 public:
     37     virtual void First() = 0;
     38     virtual void Next() = 0;
     39     virtual bool IsDone() const = 0;
     40     virtual Node *CurrentItem() const = 0;
     41 };
     42 
     43 class JTListIterator : public Iterator
     44 {
     45 public:
     46     JTListIterator(JTList *pList) : m_pJTList(pList), m_pCurrent(NULL){}
     47 
     48     virtual void First();
     49     virtual void Next();
     50     virtual bool IsDone() const;
     51     virtual Node *CurrentItem() const;
     52 
     53 private:
     54     JTList *m_pJTList;
     55     Node *m_pCurrent;
     56 };
     57 
     58 JTList::~JTList()
     59 {
     60     Node *pCurrent = m_pHead;
     61     Node *pNextNode = NULL;
     62     while (pCurrent)
     63     {
     64         pNextNode = pCurrent->pNext;
     65         delete pCurrent;
     66         pCurrent = pNextNode;
     67     }
     68 }
     69 
     70 long JTList::GetCount()const
     71 {
     72     return m_lCount;
     73 }
     74 
     75 Node *JTList::Get(const long index) const
     76 {
     77     // The min index is 0, max index is count - 1
     78     if (index > m_lCount - 1 || index < 0)
     79     {
     80         return NULL;
     81     }
     82 
     83     int iPosTemp = 0;
     84     Node *pNodeTemp = m_pHead;
     85     while (pNodeTemp)
     86     {
     87         if (index == iPosTemp++)
     88         {
     89             return pNodeTemp;
     90         }
     91         pNodeTemp = pNodeTemp->pNext;
     92     }
     93     return NULL;
     94 }
     95 
     96 Node *JTList::First() const
     97 {
     98     return m_pHead;
     99 }
    100 
    101 Node *JTList::Last() const
    102 {
    103     return m_pTail;
    104 }
    105 
    106 bool JTList::Includes(const int &value) const
    107 {
    108     Node *pNodeTemp = m_pHead;
    109     while (pNodeTemp)
    110     {
    111         if (value == pNodeTemp->value)
    112         {
    113             return true;
    114         }
    115         pNodeTemp = pNodeTemp->pNext;
    116     }
    117     return false;
    118 }
    119 
    120 void JTList::Append(const int &value)
    121 {
    122     // Create the new node
    123     Node *pInsertNode = new Node;
    124     pInsertNode->value = value;
    125     pInsertNode->pNext = NULL;
    126 
    127     // This list is empty
    128     if (m_pHead == NULL)
    129     {
    130         m_pHead = m_pTail = pInsertNode;
    131     }
    132     else
    133     {
    134         m_pTail->pNext = pInsertNode;
    135         m_pTail = pInsertNode;
    136     }
    137     ++m_lCount;
    138 }
    139 
    140 void JTList::Remove(Node *pNode)
    141 {
    142     if (pNode == NULL || m_pHead == NULL || m_pTail == NULL)
    143     {
    144         return;
    145     }
    146 
    147     if (pNode == m_pHead) // If the deleting node is head node
    148     {
    149         Node *pNewHead = m_pHead->pNext;
    150         m_pHead = pNewHead;
    151     }
    152     else
    153     {
    154         // To get the deleting node's previous node
    155         Node *pPreviousNode = NULL;
    156         Node *pCurrentNode = m_pHead;
    157         while (pCurrentNode)
    158         {
    159             pPreviousNode = pCurrentNode;
    160             pCurrentNode = pCurrentNode->pNext;
    161             if (pCurrentNode == pNode)
    162             {
    163                 break;
    164             }
    165         }
    166 
    167         // To get the deleting node's next node
    168         Node *pNextNode = pNode->pNext;
    169 
    170         // If pNextNode is NULL, it means the deleting node is the tail node, we should change the m_pTail pointer
    171         if (pNextNode == NULL)
    172         {
    173             m_pTail = pPreviousNode;
    174         }
    175 
    176         // Relink the list
    177         pPreviousNode->pNext = pNextNode;
    178     }
    179 
    180     // Delete the node
    181     delete pNode;
    182     pNode = NULL;
    183     --m_lCount;
    184 }
    185 
    186 void JTList::RemoveAll()
    187 {
    188     delete this;
    189 }
    190 
    191 void JTListIterator::First()
    192 {
    193     m_pCurrent = m_pJTList->First();
    194 }
    195 
    196 void JTListIterator::Next()
    197 {
    198     m_pCurrent = m_pCurrent->pNext;
    199 }
    200 
    201 bool JTListIterator::IsDone() const
    202 {
    203     return m_pCurrent == m_pJTList->Last()->pNext;
    204 }
    205 
    206 Node *JTListIterator::CurrentItem() const
    207 {
    208     return m_pCurrent;
    209 }
    210 
    211 int main()
    212 {
    213     JTList *pJTList = new JTList;
    214     pJTList->Append(10);
    215     pJTList->Append(20);
    216     pJTList->Append(30);
    217     pJTList->Append(40);
    218     pJTList->Append(50);
    219     pJTList->Append(60);
    220     pJTList->Append(70);
    221     pJTList->Append(80);
    222     pJTList->Append(90);
    223     pJTList->Append(100);
    224 
    225     Iterator *pIterator = new JTListIterator(pJTList);
    226 
    227     // Print the list by JTListIterator
    228     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
    229     {
    230         cout << pIterator->CurrentItem()->value << "->";
    231     }
    232     cout << "NULL" << endl;
    233 
    234     // Test for removing
    235     Node *pDeleteNode = NULL;
    236     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
    237     {
    238         pDeleteNode = pIterator->CurrentItem();
    239         if (pDeleteNode->value == 100)
    240         {
    241             pJTList->Remove(pDeleteNode);
    242             break;
    243         }
    244     }
    245 
    246     // Print the list by JTListIterator
    247     for (pIterator->First(); !pIterator->IsDone(); pIterator->Next())
    248     {
    249         cout << pIterator->CurrentItem()->value << "->";
    250     }
    251     cout << "NULL" << endl;
    252 
    253     delete pIterator;
    254     delete pJTList;
    255 
    256     return 0;
    257 }
  • 相关阅读:
    Java工作中常用到的工具
    得到区块链直播记录
    如何高效的解决问题
    pgsql数据库应用两点注意
    flask如何使模板返回大文件,又不消耗大量内存
    python内存诊断
    pycharm整体缩进的快捷键
    gdb生成的core文件位置
    gdb源码安装,指定使用的python版本
    gdb源码安装过程中的问题:no termcap library found
  • 原文地址:https://www.cnblogs.com/raichen/p/5675480.html
Copyright © 2011-2022 走看看