8 Listas Encadenadas 2a Parte
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

8 Listas Encadenadas 2a Parte

on

  • 2,707 views

 

Statistics

Views

Total Views
2,707
Views on SlideShare
2,703
Embed Views
4

Actions

Likes
0
Downloads
32
Comments
0

1 Embed 4

http://www.slideshare.net 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

8 Listas Encadenadas 2a Parte Presentation Transcript

  • 1. Implantación de listas en C++ Apoyo SSD5
  • 2. Una Plantilla de la Clase Lista En esta sección examinaremos la implantación de una clase de lista encadenada (linked list class). Iniciaremos examinando algunos requerimientos importantes que queremos que nuestra clase soporte. Mtl Lourdes Cahuich 2
  • 3. Lista encadenada Asumamos que la lista de la clase, que llamaremos LinkedList, necesita soportar solamente recorridos hacia adelante. Por esta razón, podemos implantar la clase como una lista sencillamente- encadenada. Mtl Lourdes Cahuich 3
  • 4. Lista encadenada También podemos asumir que la clase LinkedList necesita soportar la inserción y eliminación de elementos del frente y detrás de la lista. Para soportar este requerimiento, nuestra clase mantendrá apuntadores al inicio y al final de la lista. Mtl Lourdes Cahuich 4
  • 5. Lista encadenada Finalmente, nos gustaría usar esta clase para almacenar listas de enteros, cadenas de caracteres, o cualquier tipo de datos. Esto requiere que la clase sea una plantilla (template). Mtl Lourdes Cahuich 5
  • 6. template <class T> class LinkedList { public: LinkedList(); // constructor default LinkedList(const LinkedList<T>& src); //constructor copy ~LinkedList(); // Destructor T& front(); //Accesar al primer elemento T& back(); //Accesar al último elemento int size(); //Total de elementos bool empty(); //Si esta vacia la lista void push_front(const T&); //Insertar al inicio void push_back(const T&); //Insertar al final void pop_front(); //Quitar elemento del inicio void pop_back(); //Quitar elemento del final void dump(); //sacar los elementos de la lista }; Mtl Lourdes Cahuich 6
  • 7. Representación de Nodos Ahora que tenemos una idea de las funciones miembro que la clase implanta, enfoquémonos y pensemos en como podemos representar un nodo de la lista encadenada. Sabemos que un nodo debe almacenar los datos de los elementos y cualquier información necesaria para mantener la estructura de la lista encadenada. Mtl Lourdes Cahuich 7
  • 8. Lista encadenada Debido a se trata de la implantación de una lista sencillamente-encadenada, la única información que requerimos almacenar es un apuntador al siguiente nodo de la lista Mtl Lourdes Cahuich 8
  • 9. template <class T> class LinkedList { private: class Node { T data; Node* next; }; public: // aquí van elementos públicos ... Mtl Lourdes Cahuich 9
  • 10. Lista encadenada La clase anterior es una representación adecuada de un nodo para una lista sencillamente-encadenada. Contiene un elemento para almacenar los datos para el nodo y un apuntador al siguiente nodo. Mtl Lourdes Cahuich 10
  • 11. Lista encadenada Dentro del contexto de nuestra clase de lista encadenada, la clase Node requiere de más características. Primero, agregamos un constructor que permite la inicialización de los datos miembro de la clase. Mtl Lourdes Cahuich 11
  • 12. Lista encadenada También añadimos un estatuto friend que permite a las funciones miembro de la clase LinkedList acceder a los datos miembro privados de la clase Node. Mtl Lourdes Cahuich 12
  • 13. template <class T> class LinkedList { private: class Node { friend class LinkedList<T>; private: T data; Node* next; public: Node(T d, Node* n = NULL) : data(d), next(n) {}} ; Mtl Lourdes Cahuich 13
  • 14. Lista encadenada El listado anterior define completamente a la clase Node dentro de la clase LinkedList. Esto se hace principalmente por conveniencia, de manera que no tengamos que especificar el tipo de la plantilla cada vez que declaramos un objeto de tipo Node Mtl Lourdes Cahuich 14
  • 15. Lista encadenada La definición de la clase Node en este listado, agrega un constructor e incluye estatutos explícitos de los datos miembro privados y públicos. También, el estatuto friend permite a los objetos de la clase LinkedList acceder a los datos miembros de la clase Node Mtl Lourdes Cahuich 15
  • 16. Lista encadenada Se requiere agregar otros datos miembro privados a la clase LinkedList. Se añaden apuntadores al inicio y al final de la lista. La implantación de nuestra función miembro usa estos apuntadores para manipular la lista; también se añade un dato miembro para almacenar el tamaño de la lista. Mtl Lourdes Cahuich 16
  • 17. template <class T> class LinkedList { private: class Node { friend class LinkedList<T>; private: T data; Node* next; public: Node(T d, Node* n = NULL) : data(d), next(n) {}} ; Node* head; // inicio de la lista Node* tail; // final de la lista int count; // núm. Cahuich Elementos en la lista Mtl Lourdes 17
  • 18. Funciones Miembro Sencillas Ahora podemos implantar algunas de las funciones miembro más sencillas de la clase LinkedList. El siguiente listado contiene implantaciones para el constructor default y las funciones miembro front, back, size y empty. Mtl Lourdes Cahuich 18
  • 19. // Constructor por default LinkedList(void) : head(NULL), tail(NULL), count(0) {} // Regresa la referencia al 1er elemento T& front(void) { assert (head != NULL); return head->data;} // Regresa la referencia al último elemento T& back(void) { assert (tail != NULL); return tail->data;} // Regresa el contador de elementos de la lista int size(void) { return count;} // Regresa si la lista tiene o no elementos bool empty(void) { return count == 0;} Mtl Lourdes Cahuich 19
  • 20. Insertar y Remover desde el Inicio Insertar un elemento al inicio de la lista es un proceso relativamente directo. Las tareas involucradas son: Crear un objeto nuevo Node. 1. Encadenar el nuevo nodo al inicio de la lista. 2. Reposicionar el apuntador head para reflejar 3. el nuevo inicio de la lista. Incrementar el conteo de elementos en uno. 4. Mtl Lourdes Cahuich 20
  • 21. Insertar y Remover desde el Inicio Debido a que también debemos mantener un apuntador al final de la lista, existe un caso especial cuando añadimos un elemento a una lista vacía. En este caso, el elemento que agregamos no sólo se convierte en el elemento inicial de la lista, también se convierte en el elemento final de la lista. Mtl Lourdes Cahuich 21
  • 22. Insertar y Remover desde el Inicio Este caso especial es conocido como una condición de límites o boundary condition. Una condición de límites es un punto o un caso en un algoritmo, que debe ser manejado de manera diferente. Mtl Lourdes Cahuich 22
  • 23. Inserción en una lista vacía template <class T> void LinkedList<T>::push_front(T d) { Node* new_head = new Node(d, head); if (this->empty()) { head = new_head; tail = new_head; } else { head = new_head; } count++; } Mtl Lourdes Cahuich 23
  • 24. Eliminar una lista con un elemento La implantación del método pop_front, por razones similares al método push_front, también cuenta para una condición de límites. En este método, el caso especial ocurre cuando el tamaño de la lista es igual a uno. Mtl Lourdes Cahuich 24
  • 25. Eliminar una lista con un elemento template <class T> void LinkedList<T>::pop_front(void) { assert(head != NULL); Node* old_head = head; if (this->size() == 1) { head = NULL; tail = NULL; } else { head = head->next; } delete old_head; count--; } Mtl Lourdes Cahuich 25
  • 26. Insertar y Remover desde el Final Insertar un elemento al final de la lista (push_back) es similar a insertarlo al inicio (push_front). La principal diferencia es el apuntador utilizado en la operación. Al usar (push_back), insertamos un elemento, encadenando un nodo nuevo al apuntador tail. Mtl Lourdes Cahuich 26
  • 27. Insertar y Remover desde el Final El método pop_back, por otro lado, no se parece a ninguno de los métodos que hemos implantado hasta ahora. Los pasos requeridos para completar esta operación son los siguientes. Reposicionar el apuntador tail al nodo previo al último elemento. Liberar la memoria usada para el último nodo de la lista. Mtl Lourdes Cahuich 27
  • 28. Insertar y Remover desde el Final El primer paso mencionado anteriormente, reposicionar el apuntador tail, añade algo de complejidad a la implantación. Reposicionar requiere que regresemos un nodo el apuntador tail La única forma de mover un apuntador al nodo justo antes del último nodo es recorrer la lista Mtl Lourdes Cahuich 28
  • 29. El Destructor El destructor para nuestra clase de lista encadenada debe liberar cualquier memoria que pudimos haber asignado (en los métodos push_front y push_back). Podemos nivelar nuestra implantación del método pop_front para brindar una implantación del destructor simple y efectiva. Mtl Lourdes Cahuich 29
  • 30. // Destructor template <class T> LinkedList<T>::~LinkedList(void) { while (! this->empty()) { this->pop_front(); } } Mtl Lourdes Cahuich 30
  • 31. El Constructor Copy Debido a que nuestra clase de lista encadenada asigna memoria dinámicamente, necesitamos implantar un constructor copy. Esto es para asegurar que cuando se haga una copia de la lista, también se haga una copia de los datos de la lista. De otra forma, podríamos tener dos apuntadores de los objetos de la lista (head y tail) apuntando a los mismos nodos. Mtl Lourdes Cahuich 31
  • 32. // constructor copy template <class T> LinkedList<T>::LinkedList(const LinkedList<T>& src) :count(0), head(NULL), tail(NULL) { Node* current = src.head; while (current != NULL) { this->push_back(current->data); current = current->next; } } Mtl Lourdes Cahuich 32
  • 33. Cómo desplegar el contenido de la lista La última función miembro que implantamos para la clase LinkedList es el método print_list. Este método despliega el contenido de la lista al flujo de salida estándar. Mtl Lourdes Cahuich 33
  • 34. // Muestra el contenido de la lista template <class T> void LinkedList<T>::dump(void) { cout << quot;(quot;; Node* current = head; if (current != NULL) { while (current->next != NULL) { cout << current->data << quot;, quot;; current = current->next; } cout << current->data; } cout << quot;)quot; << endl; } Mtl Lourdes Cahuich 34