Implementando el patrón Iterator de una sola Lista Vinculada

STL es uno de los pilares de C++. Hace la vida mucho más fácil, especialmente cuando su atención se centra en la resolución de problemas y no desea perder tiempo implementando algo que ya está disponible y que garantiza una solución sólida. Uno de los aspectos clave de la Ingeniería de Software es evitar reinventar la rueda. Siempre se prefiere la reutilización .

Si bien depender de las funciones de la biblioteca afecta directamente nuestra eficiencia, sin tener una comprensión adecuada de cómo funciona, a veces se pierde el significado de la eficiencia de ingeniería de la que seguimos hablando. Una estructura de datos elegida incorrectamente puede volver en algún momento en el futuro para atormentarnos. La solución es sencilla. Use métodos de biblioteca, pero sepa cómo maneja las operaciones bajo el capó.

¡Basta de charla! Hoy veremos cómo podemos implementar nuestro propio patrón Iterator de una sola lista enlazada . Entonces, así es como se ve una implementación STL de Linked List: 

 

Complete Interview Preparation - GFG 

Implementación:

C++

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    // creating  a list
    vector<int> list;
 
    // elements to be added at the end.
    // in the above created list.
    list.push_back(1);
    list.push_back(2);
    list.push_back(3);
 
    // elements of list are retrieved through iterator.
    for (vector<int>::iterator it = list.begin();
                                it != list.end(); ++it)
        cout << *it << " ";
 
    return 0;
}

Java

import java.util.*;
class GFG
{
 
    public static void main(String[] args)
    {
       
        // creating  a list
        ArrayList<Integer> list = new ArrayList<>();
 
        // elements to be added at the end.
        // in the above created list.
        list.add(1);
        list.add(2);
        list.add(3);
 
        // elements of list are retrieved through iterator.
        Iterator<Integer> it = list.iterator();
        while (it.hasNext())
        {
            System.out.print(it.next() + " ");
        }
    }
}
 
// This code is contributed by pratham76

Python3

if __name__=='__main__':
     
    # Creating  a list
    list = []
  
    # Elements to be added at the end.
    # in the above created list.
    list.append(1)
    list.append(2)
    list.append(3)
     
    # Elements of list are retrieved
    # through iterator.
    for it in list:
        print(it, end = ' ')
     
# This code is contributed by rutvik_56

C#

using System;
using System.Collections.Generic;
 
public class GFG {
 
    public static void Main(String[] args) {
 
        // creating a list
        List<int> list = new List<int>();
 
        // elements to be added at the end.
        // in the above created list.
        list.Add(1);
        list.Add(2);
        list.Add(3);
 
        // elements of list are retrieved through iterator.
         
        foreach (int it in list) {
            Console.Write(it + " ");
        }
    }
}
 
 
// This code contributed by umadevi9616

Javascript

     
<script>
 
        // creating a list
        var list =  [];
 
        // elements to be added at the end.
        // in the above created list.
        list.push(1);
        list.push(2);
        list.push(3);
 
        // elements of list are retrieved through iterator.
     
        for (var i = 0; i<list.length;i++) {
            document.write(list[i] + " ");
        }
 
// This code contributed by umadevi9616
 
</script>
Producción

1 2 3 

Una de las ventajas de cin y cout es que no exigen especificadores de formato para trabajar con el tipo de datos. Esto, combinado con las plantillas, hace que el código sea mucho más limpio y legible. Aunque prefiero que el método de nombres en C++ comience con mayúsculas, esta implementación sigue las reglas de STL para imitar el conjunto exacto de llamadas a métodos, a saber, push_back, begin, end.

Aquí está nuestra propia implementación de LinkedList y su patrón Iterator:  

C++

// C++ program to implement Custom Linked List and
// iterator pattern.
#include <bits/stdc++.h>
using namespace std;
 
// Custom class to handle Linked List operations
// Operations like push_back, push_front, pop_back,
// pop_front, erase, size can be added here
template <typename T>
class LinkedList
{
    // Forward declaration
    class Node;
 
public:
    LinkedList<T>() noexcept
    {
        // caution: static members can't be
        // initialized by initializer list
        m_spRoot = nullptr;
    }
 
    // Forward declaration must be done
    // in the same access scope
    class Iterator;
 
    // Root of LinkedList wrapped in Iterator type
    Iterator begin()
    {
        return Iterator(m_spRoot);
    }
 
    // End of LInkedList wrapped in Iterator type
    Iterator end()
    {
        return Iterator(nullptr);
    }
 
    // Adds data to the end of list
    void push_back(T data);
 
    void Traverse();
 
    // Iterator class can be used to
    // sequentially access nodes of linked list
    class Iterator
    {
    public:
    Iterator() noexcept :
        m_pCurrentNode (m_spRoot) { }
 
    Iterator(const Node* pNode) noexcept :
        m_pCurrentNode (pNode) { }
 
        Iterator& operator=(Node* pNode)
        {
            this->m_pCurrentNode = pNode;
            return *this;
        }
 
        // Prefix ++ overload
        Iterator& operator++()
        {
            if (m_pCurrentNode)
                m_pCurrentNode = m_pCurrentNode->pNext;
            return *this;
        }
 
        // Postfix ++ overload
        Iterator operator++(int)
        {
            Iterator iterator = *this;
            ++*this;
            return iterator;
        }
 
        bool operator!=(const Iterator& iterator)
        {
            return m_pCurrentNode != iterator.m_pCurrentNode;
        }
 
        int operator*()
        {
            return m_pCurrentNode->data;
        }
 
    private:
        const Node* m_pCurrentNode;
    };
 
private:
 
    class Node
    {
        T data;
        Node* pNext;
 
        // LinkedList class methods need
        // to access Node information
        friend class LinkedList;
    };
 
    // Create a new Node
    Node* GetNode(T data)
    {
        Node* pNewNode = new Node;
        pNewNode->data = data;
        pNewNode->pNext = nullptr;
 
        return pNewNode;
    }
 
    // Return by reference so that it can be used in
    // left hand side of the assignment expression
    Node*& GetRootNode()
    {
        return m_spRoot;
    }
 
    static Node* m_spRoot;
};
 
template <typename T>
/*static*/ typename LinkedList<T>::Node* LinkedList<T>::m_spRoot = nullptr;
 
template <typename T>
void LinkedList<T>::push_back(T data)
{
    Node* pTemp = GetNode(data);
    if (!GetRootNode())
    {
        GetRootNode() = pTemp;
    }
    else
    {
        Node* pCrawler = GetRootNode();
        while (pCrawler->pNext)
        {
            pCrawler = pCrawler->pNext;
        }
 
        pCrawler->pNext = pTemp;
    }
}
 
template <typename T>
void LinkedList<T>::Traverse()
{
    Node* pCrawler = GetRootNode();
 
    while (pCrawler)
    {
        cout << pCrawler->data << " ";
        pCrawler = pCrawler->pNext;
    }
 
    cout << endl;
}
 
//Driver program
int main()
{
    LinkedList<int> list;
 
    // Add few items to the end of LinkedList
    list.push_back(1);
    list.push_back(2);
    list.push_back(3);
 
    cout << "Traversing LinkedList through method" << endl;
    list.Traverse();
 
    cout << "Traversing LinkedList through Iterator" << endl;
    for ( LinkedList<int>::Iterator iterator = list.begin();
            iterator != list.end(); iterator++)
    {
        cout << *iterator << " ";
    }
 
    cout << endl;
 
    return 0;
}
Producción

Traversing LinkedList through method
1 2 3 
Traversing LinkedList through Iterator
1 2 3 

Ejercicio: 
La implementación anterior funciona bien cuando tenemos un dato. Extienda este código para que funcione con un conjunto de datos incluidos en una clase.

Este artículo es una contribución de Aashish Barnwal . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *