Estructuras de datos Listas ligadas simples y dobles
Estructuras de datos Listas ligadas simples y dobles M. C. Yalu Galicia Hdez. (FCC/BUAP) 1
Listas ligadas o enlazadas simple n n Una lista ligada o enlazada es una estructura de datos dinámica, esto es, que crece y se reduce durante la ejecución. Una lista ligada es una colección lineal de objetos, conocidos como nodos, que están conectados mediante ligas o enlaces de apuntadores. cabeza Dato Nodo M. C. Yalu Galicia Hdez. (FCC/BUAP) 2
Acceso a la lista n n Se puede tener acceso a una lista ligada mediante un apuntador al primer nodo de la lista, llamado generalmente cabeza o inicio. El acceso a los nodos subsecuentes se obtiene mediante un apuntador de enlace almacenado en cada nodo. Por convención, el apuntador de enlace en el último nodo de la lista se establece como nulo, para marcar el final de la misma Los datos en una lista se almacenan dinámicamente: Cada nodo se crea en tiempo de ejecución según el usuario lo requiera. M. C. Yalu Galicia Hdez. (FCC/BUAP) 3
Listas ligadas n n Cada nodo esta constituido por dos campos: Información (que puede ser cualquier tipo de dato o un objeto) y enlace (referencia o apuntador). Un nodo se implementa usando una clase autoreferenciada. Una clase autoreferenciada contiene una referencia que apunta a un objeto de la misma clase. dato sgte Class Nodo { int dato; //información Nodo sgte; //enlace Nodo }; Nodo( ); Nodo(int x); 4
Listas ligadas simples n n n Para marcar el inicio o cabeza de la lista se utiliza una referencia a nodo, llamada normalmente cabeza, inicio o principio. Opcionalmente se puede contar con una referencia al último nodo de la lista, llamado generalmente cola, final o último. La cabeza de la lista es la única forma de acceder a los elementos de esta. Cabeza Cola 5 3 8 20 Nodo M. C. Yalu Galicia Hdez. (FCC/BUAP) 5
Listas Ligadas n n Una lista ligada sin ningún elemento se llama lista vacía, y se representa poniendo la variable cabeza a Null. Si existe cola también va a Null. Cabeza Cola Lista vacía M. C. Yalu Galicia Hdez. (FCC/BUAP) 6
Operaciones en Listas enlazadas n Las operaciones básicas que podemos realizar en una lista son: n n Creación: crear una lista vacía. Inserción: añadir elementos (nodos) a la lista en alguna posición específica: n n Al inicio Al final Entre dos nodos de la lista Eliminación: quitar un nodo de la lista de alguna posición específica n n n Al inicio Al final Dato específico x (que puede estar entre dos elementos) M. C. Yalu Galicia Hdez. (FCC/BUAP) 7
Operaciones en Listas enlazadas n n Recorrido: Moverse sobre los elementos de la lista, partiendo del inicio y llegando al final de la misma. Mostrar: Recorrer la lista mostrando los elementos en esta. Búsqueda: Recorrer la lista para verificar la existencia de un elemento dado dentro de la lista. Ordenamiento: colocar en algún orden específico (ascendente o descendente) los elementos de la lista. 8
Clase Lista Enlazada n Dadas las operaciones de una lista enlazada, podemos modelar la clase lista. Enlazada de la siguiente forma Lista. Enlazada Nodo int dato; Nodo sgte; Nodo(int x) Nodo() Nodo inicio Nodo fin Lista. Enlazada() boolean esta. Vacia() void Insertar. Al. Inicio() void Insertar. Al. Final(). . . void Eliminar. Del. Inicio() void Eliminar. Dato(). . . 9
Clase Lista Enlazada class Nodo { int dato; Nodo sgte; //por convención sgte siempre es iniciado a null Nodo( ) { dato = 0; sgte = null; } Nodo( int x) { dato = x; sgte = null; } }; class Lista. Enlazada { Nodo inicio, fin; // inicio y fin de la cola Lista. Enlazada( ) { inicio = null; fin = null; } //Lista Vacia boolean esta. Vacia() { if(inicio == null && fin == null) return true; return false; } void Insertar. Al. Inicio(int dato); . . . void Eliminar. Del. Inicio( ); . . }; M. C. Yalu Galicia Hdez. (FCC/BUAP) 10
Crear un nuevo nodo n n Los elementos (nodos) de una lista ligada se van creando dinámicamente, esto es, en tiempo de ejecución, cada vez que el usuario inserta un nuevo nodo a la lista. Para crear un nuevo nodo, se utiliza el operador new, para crear una nueva instancia de la clase Nodo. El operador New obtiene memoria del tipo solicitado y regresa una referencia a ese tipo. Ejemplo: Nodo nuevo = new Nodo(dato); n Crea un nuevo objeto de tipo Nodo n Si no hay memoria disponible new devolverá null. M. C. Yalu Galicia Hdez. (FCC/BUAP) 11
Mostrar contenido de la lista n Para mostrar el contenido de la lista tenemos que considerar dos situaciones: n n inicio Si la lista esta vacía (inicio y fin son Null), entonces no hacer nada solo indicar “lista vacía” Si la lista tiene al menos un elemento n Crear una referencia auxiliar e inicializarla con el inicio de la lista (el apuntador inicio nunca se debe perder). n Recorrer la lista utilizando la variable auxiliar hasta que fin sea null (fin de la lista) 2 dato sgte aux 5 8 aux 10 aux 15 aux Nodo aux = inicio //aux apunta donde apunta inicio while (aux != null) { System. out. println( aux. dato); //dato del nodo apuntado por aux = aux. sgte; //aux apunta donde apunta sgte } 12
Búsqueda de un dato n Para buscar un elemento de la lista tenemos que considerar dos situaciones: n n inicio Si la lista esta vacía (inicio y fin son null), entonces regresar null para indicar que no se encontró Si la lista tiene al menos un elemento n Inicializar un apuntador auxiliar con el inicio de la lista n Recorrer la lista hasta que aux sea null al mismo tiempo que compara el nodo apuntado por aux con el elemento a buscar. Si se encuentra regresar aux. fin 2 dato sgte aux 5 8 aux 10 aux Nodo aux = inicio //aux apunta donde apunta inicio while (aux != null && aux. dato != x) //busca el dato aux = aux. sgte; return aux; 15 aux 13
Insertar al inicio n Para insertar al inicio de una lista enlazada tenemos que considerar dos situaciones Si la lista esta vacía (inicio y fin son null) Si la lista tiene al menos un elemento n n inicio nuevo fin 5 3 sgte Si esta. Vacia() entonces Nodo nuevo = new Nodo(dato); inicio = nuevo; //inicio apunta donde apunta nuevo fin = nuevo; Sino Nodo nuevo = new Nodo(dato); nuevo. sgte = inicio; inicio = nuevo; Fin_si M. C. Yalu Galicia Hdez. (FCC/BUAP) 14
Insertar al final n Para insertar al final, nuevamente tenemos que considerar dos situaciones Si la lista esta vacía (inicio y fin son Null) Si la lista tiene al menos un elemento n n inicio nuevo fin sgte 5 3 Si esta. Vacia() entonces Nodo nuevo = new Nodo(dato); inicio = nuevo; //inicio apunta donde apunta nuevo fin = nuevo; Sino Nodo nuevo = new Nodo(dato); fin. sgte = nuevo; //el nodo final se liga al nuevo fin = nuevo; //se recorre fin Fin_si M. C. Yalu Galicia Hdez. (FCC/BUAP) 15
Insertar entre dos nodos n Para insertar entre dos nodos, tenemos que considerar dos situaciones: n n Si la lista esta vacía (inicio y fin son Null) Si la lista tiene al menos un elemento, localizar posición del nuevo nodo a insertar. Por ejemplo después del 5 n n inicio 17 Se necesita otro apuntador (aux). En donde se coloca? Insertar nuevo nodo aux fin 5 nuevo 56 8 9 34 sgte 16
Actividad Individual Actividad: Implementa el método insertar. Antes(x, y) de la clase Lista. Ligada. Insertar un nodo antes de otro. Por ejemplo el nodo con dato x = 9 antes del nodo con dato y =15 inicio 2 fin 6 nuevo 23 15 9 57 sgte 17
Actividad Individual Actividad: Implementa el método insertar() de la clase Lista. Ligada. Supongamos que la lista es una lista ordenada ascendentemente, por lo tanto el método insertar() debe insertar ordenadamente el dato dado como parámetro (por ejemplo el 9) inicio 2 fin 6 nuevo 23 15 9 57 sgte 18
Actividad colaborativa n n n Colaborativamente: Trabajen en equipo, asegurándose de que todos comprenden el funcionamiento de una Lista Ligada y como insertar/eliminar nodos de la lista Criterios para el éxito: Cada integrante del equipo deberá ser capaz de explicar al grupo el procedimiento para insertar ordenadamente Responsabilidad Individual: Cualquier integrante del equipo podrá ser seleccionad@ aleatoriamente para exponer su método. Su calificación será la del equipo. M. C. Yalu Galicia Hdez. (FCC/BUAP) 19
Eliminar del inicio n Para eliminar del inicio tenemos que considerar tres situaciones: n n Si la lista esta vacía (inicio y fin son Null), no hacer nada, solo indicar “lista vacía” Si la lista tiene solo UN elemento (inicio == fin), entonces eliminarlo y actualizar inicio y fin a Null. Si la lista tiene más de un elemento Donde se deben colocar el otro apuntador? inicio 2 65 tmp fin 8 23 15 Nodo tmp; tmp = inicio; //tmp apunta donde apunta inicio = inicio. sgte; //inicio se recorre uno delete(tmp); //se borra el nodo completo 20
Eliminar del final n Para eliminar del final tenemos que considerar tres situaciones: n n inicio 19 tmp n Si la lista esta vacía (inicio y fin son null), no hacer nada, solo indicar “lista vacía” Si la lista tiene solo UN elemento (inicio == fin), entonces eliminarlo y actualizar inicio y fin a Null. Si la lista tiene más de un elemento fin 5 3 tmp 10 fin 15 tmp Nodo tmp = inicio; //tmp apunta donde apunta inicio while (tmp. sgte != fin) tmp = tmp. sgte; fin = tmp; //fin apunta donde apunta tmp Fin. sgte = null; 21
Eliminar un dato Para eliminar un elemento específico, tenemos que considerar varias situaciones: n n inicio 2 Localizar el elemento a borrar (por ejemplo el 8) n Cuantos apuntadores auxiliares se necesitan? n Donde se deben colocar? , en el nodo con el dato o en el nodo anterior? fin 15 ant act 8 10 35 act Nodo act, act; ant = act = inicio; while (act != null && act. dato != x) { ant=act; act=act. sgte; } if (act != null) { ant. sgte = act. sgte; if(act == fin) fin = ant; } 22
Eliminar un dato n n n Si la lista esta vacía (inicio y fin son Null), no hacer nada, solo indicar “lista vacía” ¿Qué pasa si el elemento a borrar está al inicio? (por ejemplo el 2) n Llamar a Eliminar. Del. Inicio() ¿Qué pasa si el elemento a borrar está al final? (por ejemplo el 15) n Llamar a Eliminar. Del. Final() inicio 2 fin 9 8 23 15 23
Actividad Individual Actividad: Escribir el método para eliminar un elemento antes de otro. Ejemplo borrar el elemento antes del 9 inicio 6 fin 15 9 2 45 24
Actividad colaborativa n n n Colaborativamente: Trabajen en equipo, asegurándose de que todos comprenden el funcionamiento de una Lista Ligada y como insertar/eliminar nodos de la lista Criterios para el éxito: Cada integrante del equipo deberá ser capaz de explicar al grupo el procedimiento para insertar ordenadamente Responsabilidad Individual: Cualquier integrante del equipo podrá ser seleccionad@ aleatoriamente para exponer su método. Su calificación será la del equipo. M. C. Yalu Galicia Hdez. (FCC/BUAP) 25
¿Que aprendimos? M. C. Yalu Galicia Hdez. (FCC/BUAP) 26
Tipos de listas ligada De acuerdo con su conformación, las listas se pueden clasificar en: n n Lista ligada simple n Es aquella en la que cualquiera de sus nodos tiene un único inmediato sucesor y un único inmediato antecesor, exepto el primero y el último nodo que no tienen antecesor ni sucesor respectivamente. inicio 2 fin 9 8 23 M. C. Yalu Galicia Hdez. (FCC/BUAP) 15 27
Tipos de listas ligada n Lista circular (o en anillo) n n n inicio 2 Es aquella en la que en lugar de almacenar un apuntador a null en el campo sgte del último nodo de la lista, se hace que el último elemento apunte al principio de la lista. En una lista circular cada nodo de la lista es accesible desde cualquier otro nodo de ella. Es decir, dado un nodo se puede recorrer toda la lista completa. En una lista enlazada simple solo es posible recorrerla por completo si se parte del primer nodo. Las operaciones de concatenación y división de listas son mas eficaces con listas circulares fin 9 8 23 15 28
Actividad colaborativa Actividad: En binas escribir el método insertar al inicio de la clase Lista Ligada Circular 1 ero. Suponiendo que existe el apuntador FIN Suponiendo que no existe FIN inicio 6 fin 15 9 2 45 29
Tipos de listas ligada n Lista doblemente enlazada n n n En las listas anteriores el recorrido de ellas solo podía hacerse en un único sentido: de izquierda a derecha (principio a final). En numerosas ocasiones se requiere recorrer las listas en ambas direcciones Las listas que pueden recorrerse en ambas direcciones se denominan listas doblemente enlazadas En estas listas cada nodo consta del campo de información (dato) y de dos campos de enlace o apuntadores: anterior(ant) y siguiente (sgte), que apuntan hacia adelante y hacia atrás. inicio fin 2 ant 9 sgte ant 8 sgte ant 15 sgte ant sgte 30
Clase Lista doblemente enlazada n Dadas las operaciones de una lista doblemente enlazada, podemos modelar la clase lista. Doble de la siguiente forma Lista. Enlazada. Doble Nodo. D int dato; Nodo. D sgte; Nodo. D ant; Nodo. D(int) Nodo. D() Nodo. D inicio Nodo. D fin Lista. Doble() esta. Vacia() Insertar. Al. Inicio() Insertar. Al. Final(). . . Eliminar. Del. Inicio() Eliminar. Dato(). . . 31
Clase Lista doblemente enlazada class Nodo. D { int dato; Nodo. D sgte; Nodo. D ant; //por convención sgte siempre es iniciado a null Nodo. D( ) { dato = 0; sgte = null; ant = null; } Nodo. D( int x) { dato = x; sgte = null; ant = null} }; class Lista. Doble { Nodo. D inicio, fin; // inicio y fin de la cola Lista. Doble( ) { inicio = null; fin = null; } //Lista Vacia bool esta. Vacia() { if (inicio == null && fin == null) return true; return false; } void Insertar (int dato); void Eliminar. Dato( int x); . . M. C. Yalu Galicia Hdez. }; (FCC/BUAP) 32
Inserción n inicio ant La inserción de un nodo a la derecha de un nodo especificado, apuntado por aux, puede presentar varios casos n La lista esta vacía, entonces actualizar inicio y fin al nuevo nodo n Insertar dentro de la lista: existe un elemento anterior y otro posterior de X n Insertar al inicio de la lista. Se requiere que inicio sea modificado n Insertar a la derecha del nodo al final de la lista. Se requiere que fin sea modificado aux sgte ant nuevo fin sgte ant x sgte ant sgte 33
Eliminación n La eliminación es directa n Si la lista tiene un simple nodo, entonces los apuntadores inicio y fin son puestos a NULL. n Si el nodo al final de la lista debe ser eliminado, el fin debe modificarse para apuntar al predecesor del nodo que se va a eliminar de la lista n Si el nodo al inicio de la lista debe ser eliminado, el inicio debe modificarse y apuntar al siguiente de la lista n La eliminación dentro de la lista del nodo aux es como sigue: Aux. ant. sgte= aux. sgte inicio ant aux sgte ant fin sgte Aux. sgte. ant= aux. ant sgte 34
Actividad colaborativa Actividad: En ternas implementen el método insertar() de la clase Lista. Doble. Supongamos que la lista es una lista ordenada ascendentemente, por lo tanto el método insertar() debe insertar ordenadamente el dato dado como parámetro (por ejemplo el 9) inicio fin 4 ant 7 sgte ant nuevo 15 sgte ant 9 36 sgte ant sgte 35
Actividad colaborativa n n n Colaborativamente: Trabajen en equipo, asegurándose de que todos comprenden el funcionamiento de una Lista doblemente Ligada y como insertar/eliminar nodos de la lista Criterios para el éxito: Cada integrante del equipo deberá ser capaz de explicar al grupo el procedimiento para insertar ordenadamente en una lista doble Responsabilidad Individual: Cualquier integrante del equipo podrá ser seleccionad@ aleatoriamente para exponer su método. Su calificación será la del equipo. M. C. Yalu Galicia Hdez. (FCC/BUAP) 36
¿Que aprendimos? M. C. Yalu Galicia Hdez. (FCC/BUAP) 37
- Slides: 37