Una lista es un contenedor secuencial en el que se pueden insertar y borrar elementos independientemente del tamaño del contenedor. Para insertar un elemento cualquiera debemos ir recorriendo la lista, lo que pudiera hacer creer que las listas son menos prácticas que los vectores, pero estas tienen sus ventajas: una inserción en medio de la lista no requiere mover todos los elementos que se encuentran después del punto de inserción mientras que en un vector es necesario recorrer todos los elementos para abrir espacio al nuevo elemento. Las operaciones básicas de los diferentes tipos de listas son las misma sólo que se realizan de formas diferentes dependiendo de la naturaleza de cada una de ellas. Estas operaciones básicas son: Insertar, Eliminar, editar y consultar un dato en la estructura. Inserción de un elemento en una lista El nuevo elemento que se desea incorporar a una lista se puede insertar de distintas formas, según la posición de inserción. Ésta puede ser:
De ser Lista Doble y/o Lista Circular Doble Quitar un nodo de una lista supone realizar el enlace de dos nodos, el nodo anterior con el nodo siguiente al que se desea eliminar. La referencia adelante del nodo anterior debe apuntar al nodo siguiente, y la referencia atrás del nodo siguiente debe apuntar al nodo anterior. El algoritmo es similar al del borrado para una lista simple. Ahora, la dirección del nodo anterior se encuentra en la referencia atrás del nodo a borrar. Los pasos a seguir son:
Editar un elemento en una lista La operación editar un elemento en una lista recorre la lista hasta encontrar la posición del nodo al que se desea modificar la información del elemento y actualiza la información del nodo por el nuevo elemento. El algoritmo, una vez modificada la información del nodo, devuelve la referencia a ese nodo (en caso negativo, devuelve null). Otro planteamiento es que el método devuelva true si se pudo modificar la información del nodo con el elemento, y false si no se pudo realizar la operación. Consulta de un elemento en una lista La operación búsqueda de un elemento en una lista enlazada recorre la lista hasta encontrar el nodo con el elemento. El algoritmo, una vez encontrado el nodo, devuelve la referencia a ese nodo (en caso negativo, devuelve null). Otro planteamiento es que el método devuelva true si encuentra el nodo con el elemento, y false si no está en la lista.
Clasificación de las listas enlazadas Los diferentes tipos de listas dependen de la forma de enlazar los nodos, son:
Estructura conformada por un elemento fundamental denominado Nodo. El Nodo es un elemento que contiene la información y la dirección del siguiente elemento, el primer elemento creado se le denomina cabeza y es la referencia para el desarrollo de las diversas acciones en la Lista. Para comprender de una mejor manera el concepto de Listas Simples es necesario, primeramente, conocer la estructura básica de un nodo. En general un nodo consta de dos partes:
Una lista enlazada, en su forma mas simple, es una colección de nodos que juntos forman un orden lineal. El ordenamiento esta determinado de tal forma que cada nodo es un objeto que guarda una referencia a un elemento y una referencia, llamado siguiente, a otro nodo. La idea principal es que se cree un nuevo nodo, se pone su enlace siguiente para que se referencie al mismo objeto que la cabeza, y entonces se pone que la cabeza apunte al nuevo nodo.
Podría parecer extraño tener un nodo que referencia a otro nodo, pero tal esquema trabaja fácilmente. La referencia siguiente dentro de un nodo puede ser vista como un enlace o apuntador a otro nodo. De igual nodo, moverse de un nodo a otro siguiendo una referencia al siguiente es conocida como salto de enlace o salto de apuntador. Como en un arreglo, una lista simple enlazada guarda sus elementos en un cierto orden. Este orden está determinado por la cadenas de enlaces siguientes yendo desde cada nodo a su sucesor en la lista. A diferencia de un arreglo, una lista simple enlazada no tiene un tamaño fijo predeterminado, y usa espacio proporcional al número de sus elementos. Asimismo, no se emplean números índices para los nodos en una lista enlazada. Por lo tanto, no se puede decir sólo por examinar un nodo si este es el segundo, quinto u otro nodo en la lista.
>Ejemplo de Insertar Se inserta en una Lista Simple los números 10, 1, 23, 2, 12.La estructura se implemento en la clase ListaS, adicional a esto la estructura requiere de un elemento fundamental en el almacenamiento de los objetos denominado nodo que es la base de su implementación, este elemento fue definido en la clase Nodo. Nodo es un elemento que esta compuesto por la información (elemento) almacenada y un apuntador al siguiente nodo, entendiendo por apuntador la dirección del nodo que le sigue. ListaS es un conjunto de nodos entrelazados entre si, cuyo origen es con la creación de un Nodo al que se le denomina “cabeza”, punto de referencia para el desarrollo de los diversos procesos como lo son: la inserción de elementos que se puede realizar al inicio o fin de la lista es decir que los elementos no están ordenados en la estructura. En el proceso de eliminar un objeto sólo se modifica el apuntador de su predecesor hacia el nodo siguiente del que se desea eliminar, la estructura también tiene implementación de métodos como buscar y editar un elemento, conocer los datos almacenados y conocer el tamaño, para esto se define un atributo llamado “tamanio” para controlar la cantidad de elementos que posee la lista siendo este el tamaño de la estructura. Adicionalmente a esto, con la Lista Simple es posible generar un Iterador de Lista Simple (IteradorLS) que permite recorrer de una forma más sencilla la estructura. La implementación de la Clase ListaS se ilustra en el siguiente diagrama de clase:
En una lista doblemente enlazada cada nodo tiene una referencia al nodo siguiente, el cual apunta al siguiente nodo en la lista, y al nodo anterior el cual apunta al nodo previo en la lista. Al igual que en las implementaciones de otras estructuras, en la lista doblemente enlazada los nodos cabecera y final tienen referencias a null. Una buena analogía de una lista doble enlazada sería un tren, donde cada vagón esta conectado con el que le precede y el que le sigue.
La implementación de la estructura se encuentra en la clase ListaD, está se basa en el elemento fundamental denominado “NodoD” implementado en la clase NodoD, NodoD es un nodo doble que esta conformado por la información (elemento) almacenada y dos apuntadores un que direcciona al nodo que le antecede y otro que direcciona al siguiente nodo, este es requerido por la ListaS para almacenar los elementos de la lista. ListaD es un conjunto de Nodo dobles “NodoD” ligados entre si, originada por la creación que un NodoD llamado “cabeza” que es el punto de referencia para los diferentes procesos de la estructura, en el proceso de inserción se tuvo en cuenta modificar los apuntadores del nuevo nodo creado y del nodo que le antecede si se inserta al final de la lista ó del nodo “cabeza” en caso que se inserte al inicio de la lista, igualmente para el proceso de eliminación se deben modificar los apuntadores de los nodo asociados con el nodo a eliminar. Así mismo, la estructura cuenta con operaciones tale como: buscar y modificar un elemento, además de conocer el tamaño de la estructura su comportamiento es similar al de la Lista Simple solo difieren del elemento fundamental para el almacenamiento de sus objetos. Adicionalmente a esto, con la Lista Doble es posible generar un Iterador de Lista Doble (IteradorLD) que permite recorrer de una forma más sencilla la estructura. La implementación de la Clase ListaD se ilustra en el siguiente diagrama de clase:
En las listas lineales simples o dobles siempre hay un primer nodo y un último nodo que tiene el campo de enlace a nulo. Esto, porque se delimita el comienzo y el término de la misma. Una lista circular, por su naturaleza cíclica, no tiene ni principio ni fin. No obstante, es útil y recomendable establecer un nodo de referencia a partir del cual se acceda a la lista y así poder conocer la posición inicial y acceder a sus operaciones insertar, borrar etc. Una lista circularmente enlazada tiene el mismo tipo de nodos que una lista simple enlazada. Esto es, cada nodo en una lista circularmente enlazada tiene un apuntador siguiente y una referencia a un elemento. Pero no hay una cabeza o cola en la lista circularmente enlazada. En vez de tener que el apuntador del _ultimo nodo sea null, en una lista circularmente enlazada, este apunta de regreso al primer nodo. Por lo tanto, no hay primer nodo o último. Si se recorren los nodos de una lista circularmente enlazada desde cualquier nodo usando los apuntadores sig, se ciclará a través de los nodos.
Una lista circular catalogada como una estructura lineal dinámica, es una lista simple cuya particularidad es que el último nodo de la lista en vez de apuntar a nada apunta a la primera posición de la lista, característica que hace circular el comportamiento de la estructura. Esta estructura fue implementada en la clase ListaC, consiste en un conjunto de Nodo simples ligados que son el elemento fundamental de la estructura definido en la clase Nodo. Nodo es un elemento que esta compuesto por la información (elemento) almacenada y un apuntador al siguiente nodo, entendiendo por apuntador la dirección del nodo que le sigue. ListaC es un conjunto de Nodo entrelazados entre si, con la creación de un Nodo denominado “cabeza” se crea la estructura, la cabeza es el punto de referencia para el desarrollo de los diversos procesos como lo son: la inserción de elementos que se puede realizar al inicio o fin de la lista teniendo en cuenta que al inserta al inicio se debe modificar la “cabeza” por el nuevo nodo, al insertar al final se deben modificar los apuntadores del penúltimo y el nuevo nodo para que este apunte a la “cabeza”, los elementos no están ordenados en la estructura. Al eliminar un objeto sólo se modifica el apuntador de su predecesor hacia el nodo siguiente del que se desea eliminar, la estructura también tiene implementación de métodos como buscar y editar un elemento, conocer los datos almacenados y conocer el tamaño, para esto se define un atributo llamado “tamanio” para controlar la cantidad de elementos que posee la lista siendo este el tamaño de la estructura. Adicionalmente a esto, con la Lista Circular es posible generar un Iterador de Lista Circular (IteradorLC) que permite recorrer de una forma más sencilla la estructura.La implementación de la Clase ListaC se ilustra en el siguiente diagrama de clase:
En una lista circular doblemente enlazada, cada nodo tiene dos enlaces, análogamente a la lista doblemente enlazada lineal, el cambio radica en que el enlace anterior del primer nodo apunta al último y el enlace siguiente del último nodo, apunta al primero.
Como en una lista doblemente enlazada, las inserciones y eliminaciones pueden ser hechas desde cualquier punto con acceso a algún nodo contiguo. Aunque estructuralmente una lista circular doblemente enlazada no tiene ni principio ni fin, un puntero de acceso externo (centinela) puede establecer el nodo apuntado que está en la cabeza o al nodo final, y así mantener el orden como en una lista doblemente enlazada. La búsqueda y los algoritmos de ordenación se simplifican si se usan los llamados Nodos Centinelas o cabecera, donde cada elemento apunta a otro elemento y nunca a nulo. El Nodo Centinela o Puntero Cabeza contiene, como otro, un puntero siguiente que apunta al que se considera como primer elemento de la lista También contiene un puntero previo que hace lo mismo con el último elemento. El Nodo Centinela es definido como otro nodo en una lista doblemente enlazada. Si los punteros anterior y siguiente apuntan al Nodo Centinela la lista se considera vacía. En otro caso, si a la lista se le añaden elementos ambos puntero apuntarán a otros nodos. Estos Nodos Centinelas simplifican muchos las operaciones pero hay que asegurarse de que los punteros anterior y siguiente existen en cada momento. Ejemplo de insertar Se desea insertar en una Lista Circular Doble los datos: 23, 10,16, 1 y 29.
Estructura lineal dinámica implementada en la clase ListaCD, cuya particularidad es que el último nodo de la lista en vez de apuntar a nada apunta a la primera posición de la lista y está a su vez posee un a puntador hacia el ultimo nodo de la lista, característica que hace circular el comportamiento de la estructura. La implementación de la estructura se basa en el elemento fundamental denominado “NodoD” implementado en la clase NodoD, NodoD es un nodo doble que esta conformado por la información (elemento) almacenada y dos apuntadores uno que direcciona al nodo que le antecede y otro que direcciona al siguiente nodo. La implementación de ListaCD consiste en un conjunto de Nodo dobles “NodoD” ligados entre si, estructura que se crea con un NodoD llamado “cabeza” que es el punto de referencia para los diferentes procesos de la estructura, en el proceso de inserción se tuvo en cuenta modificar los apuntadores del nuevo creado y del nodo que le antecede si se inserta al final de la lista ó del nodo “cabeza” en caso que se inserte al inicio de la lista, igualmente para el proceso de eliminación se deben modificar los apuntadores de los nodos asociados con el nodo que se desea eliminar. Así mismo, la estructura cuenta con operaciones tale como: buscar y modificar un elemento, además de conocer el tamaño. Adicionalmente a esto, con la Lista Circular Doble es posible generar un Iterador de Lista Circular Doble (IteradorLCD) que permite recorrer de una forma más sencilla la estructura. La implementación de la Clase ListaCD se ilustra en el siguiente diagrama de clase: