Está en la página 1de 38

PROGRAMACION II

Listas Simplemente Enlazadas


Oswaldo Velez-Langs, PhD
oswaldovelez@correo.unicordoba.edu.co
Agenda
• Conceptos

• Implementación

• Modelo de Listas

• Algoritmos Básicos
Definición
• Estructura de datos lineal.
• Colección de elementos homogéneos entre los que
existe una relación lineal
 Para cada elemento, se puede decir cuál es su sucesor (en
caso de existir).
 Cada elemento de la lista, a excepción del primero, tiene un
único predecesor
 Cada elemento de la lista, a excepción del último, tiene un
único sucesor
• Colección de nodos enlazados entre sí
Lista
Nodo1 Nodo2 Nodo n
Ejemplo
Clasificación de Listas
• Por la naturaleza de la información:
 Ordinales: la posición de los elementos en la estructura la
determina su orden de llegada.
 Calificadas: Cada elemento de la lista se identifica por un valor
único (clave). En función de que exista o no relación entre la
clave y la posición pueden ser: no ordenadas y ordenadas.
• Por la forma de ocupar el espacio físico:
 Listas densas: la posición de un elemento es:
 1 si es el primer elemento.
 n si el elemento anterior es n-1.
 Listas enlazadas: la posición de un elemento es:
 k si es el primer elemento, siendo k conocido.
 j si no es el primer elemento, posición contenida en el elemento
anterior.
• Por el tipo de tecnología:
 En memoria central: estáticas y dinámicas.
 En memoria externa (no se contemplan en la asignatura).
Implementación de Listas
• Una lista es independiente de una forma específica de codificación

• Pueden usarse:
 Estructuras Estáticas (matrices)
 Estructura Dinámica (tecnología de punteros / referencias)
Lista densa con estructura estática
• Debeconocerse de antemano el número de
elementos previsto en la lista
• Problemas de mantenimiento: inserción y
eliminación poco eficientes
• Lista densa:
Lista enlazada con estructura estática

• Lista enlazada:
Lista 10 12 13 21

• Matriz con referencias a nodos ocupados y huecos


(limitado
0 a 18 elementos):
2 3 4 5 6 7 8
1 10 77 12 26 21 11 13 18
2 3 4 7 6 0 8 5 0
Estructura dinámica: Punteros
• Tecnología de punteros

• Lista:
 Variable estática que apunta al primer elemento de una lista.

• Nodo de una lista:


 Información de tipo T
 Enlace al nodo siguiente

• Valores especiales:
 Primer elemento de la lista
 Último elemento de la lista
Representación de una lista enlazada

Memoria estática
Lista

10 Memoria dinámica
12
21 *
13
Otras posibilidades
 Con cabecera y/o centinela.

 Bidireccionales (doblemente enlazadas).

 Circulares.

 Combinación de las anteriores.


Modelo.

Lista
Memoria estática

Memoria dinámica

inicio
nombre

NodoLista 10
12
n
21 u
l
13 l
Aspectos sintácticos: clase Lista.
• La clase Lista identifica una referencia (puntero) a un
objeto (o null).
• La declaración de la clase Lista debe incluir:
 Las variables miembro.
 El/los constructor/es.
 [Opcional] Otros métodos que vayan a ser utilizados por objetos
externos.
• Ejemplo:
public class Lista {
NodoLista inicio;
String nombre;
public ListaEnlazada () {
inicio = null;
nombre = null;
}
// Otros métodos
}
Aspectos sintácticos: clase NodoLista
• La estructura de datos que representa los nodos de una lista debe
contemplarse como una clase (NodoLista.java).
 Se debe declarar:
 Las variables miembro (clave y sig).
 El/los constructor/es.
 El destructor [innecesario en Java].
 [Opcional] Otros métodos que vayan a ser utilizados por objetos externos.

• Código:
class NodoLista {
int clave;
NodoLista sig;

NodoLista (int dato) {


clave = dato;
sig = null;
}
// otros métodos
}
Algoritmos básicos.
• Una sola ejecución:
 Insertar al principio.
 Eliminar el primero.

• Recorrido de la lista (recursivo):


 Sin modificar la estructura:
 Recorrido completo: Mostrar el contenido de una lista.
 Modificando la estructura:
 Recorrido completo:
 Insertar al final.
 Obtener el duplicado de una lista.
 Destruir una lista.
Proceso único. Lista

lista

• Insertar al principio.
 Crear nuevo nodo con la información de 13

inicio
nombre 10
entrada
NodoLista
 Enlazar el nuevo nodo a la lista

null
21

aux

dato

static void insertarAlPrincipio (Lista lista, int dato) {


//¡ATENCION! No se verifica la introducción de claves repetidas.
NodoLista aux;
aux = new NodoLista (dato);
aux.sig = lista.inicio;
lista.inicio = aux;
}
Inserción al principio. Modelo simplificado.
 Situación inicial.

 Creación de un nuevo nodo.

 Situación final.
Modelo de funcionamiento desde el
programa principal
public static void main (String [ ] args) {
Lista lista; //Declaración de la variable (puntero) lista de clase Lista
Memoria estática Memoria dinámica

null

Variable lista

Lista = new Lista (); // Construcción de un objeto de clase Lista


Memoria estática Memoria dinámica

inicio
nombre

Variable lista
Objeto de clase Lista

insertarAlPrincipio (lista,10); //Ejecución del método insertarAlPrincipio

Memoria estática Memoria dinámica

inicio

null
nombre 10
} Variable lista
Objeto de clase NodoLista
Objeto de clase Lista
Proceso único.
• Eliminar el primero.
Lista

lista

13

inicio
static void eliminarPrimero (Lista lista) { nombre 10
if (lista.inicio != null)
NodoLista
lista.inicio = lista.inicio.sig;
else System.out.println ("Error, lista vacia");
} 21 null

¿Y si la lista tiene un solo nodo?


Recorrido completo de la lista.
Ejemplo: Mostrar el contenido.

public void mostrarLista () {


mostrarLista (inicio);
}

static void mostrarLista (NodoLista nodoLista) {


if (nodoLista != null) {
System.out.println (nodoLista.clave + " ");
mostrarLista (nodoLista.sig);
}
else System.out.println ("FIN");
}
Modificación de la estructura. Recorrido
completo
Insertar al final. Algoritmo.
• Módulo de llamada no recursivo (Lista).
• Módulo recursivo (NodoLista).
• Devuelve un objeto de la clase NodoLista.
• Se inicializa el valor devuelto con el propio argumento:;
• Se “reemplaza” el puntero nodoLista.sig por el valor
devuelto: ); resul = nodoLista;
• En la fase de transición se genera el nuevo nodo.
nodoLista.sig = insertar (nodoLista.sig, dato);
• El método solo surte efecto en la instancia de la fase de vuelta
correspondiente al último nodo original.
Se recuerda que en Java los argumentos solo pueden
pasarse “por valor”.
Modificación de la estructura. Recorrido
completo.
Insertar al final. Código
static void insertarAlFinal (Lista l, int dato) {

//¡ATENCION! No se verifica la introduccion de claves repetidas.

l.inicio = insertarAlFinal (l.inicio,dato);

static NodoLista insertarAlFinal (NodoLista nodoLista, int dato) {

NodoLista resul = nodoLista;

if (nodoLista != null)

nodoLista.sig = insertarAlFinal (nodoLista.sig, dato);

else {

resul = new NodoLista (dato);

//resul.sig = nodoLista; (Innecesario, ya es null)

return resul;
Modificación de la estructura. Recorrido
completo .
Insertar al final. Modelo físico.
null
Instancia 3

null
8 resul
8
dato null
nodoLista

8 resul
Instancia 2
dato
nodoLista

null
4

Instancia 1 8 resul
dato
nodoLista 2

lanzadera 8

inicio
dato nombre

lista

nodoLista.sig = insertarAlFinal (nodoLista.sig, 8);


Modificación de la estructura. Recorrido
completo.
Insertar al final. Modelo simplificado
 Situación inicial.
Lista

null
2 4

inicio
nombre

NodoLista

 Fase de transición.

null
resul
8 Instancia 3

Lista

inicio

null
nombre
2 4
NodoLista

 Fase de vuelta.

null
Instancia 1 Instancia 2 8
Lista

null
4
inicio

nombre 2
NodoLista
Recorrido completo. Obtener el duplicado de
una lista.
• Combinación de algoritmos básicos:
 Recorrido completo sin modificar estructura (lista origen).
 Insertar (lista destino). Alternativas:
 En la fase de ida: insertarAlFinal.
 En la fase de vuelta: insertarAlPrincipio.
static void duplicarLista (Lista listaO, Lista listaD) {
listaD.inicio = duplicarLista (listaO.inicio);
}
static NodoLista duplicarLista (NodoLista nodoListaO) {
NodoLista resul;
NodoLista aux;
if (nodoListaO != null) {
resul = duplicarLista (nodoListaO.sig);
aux = new NodoLista (nodoListaO.clave);
aux.sig = resul;
resul = aux;
}
else resul = null;
return resul;
}
Recorrido completo. Obtener el duplicado de una lista.
• Combinación de algoritmos básicos:
 (lista origen) Recorrido completo sin modificar estructura
 (lista destino) Insertar un nodo al principio de la lista en la fase
de vuelta

static void duplicarLista (Lista listaO, Lista listaD) {


listaD.inicio = duplicarLista (listaO.inicio);
}

static NodoLista duplicarLista (NodoLista nodoListaO) {


NodoLista resul;
NodoLista aux;

if (nodoListaO != null) {
resul = duplicarLista (nodoListaO.sig);
aux = new NodoLista (nodoListaO.clave);
aux.sig = resul;
resul = aux;
}
else resul = null;
return resul;
}
Ejercicio Resuelto
• La Facultad de Ingenierías decidió implementar un parqueadero para estudiantes, el diseño
contempla un solo carril que acepta hasta 10 automóviles, los automóviles llegan por el
extremo sur del estacionamiento y salen por el extremo norte.

• Si llega un estudiante a recoger un carro, que no está en el extremo norte, se sacan todos los
automóviles de ese lado, se retira el carro y los otros carros se restablecen en el orden en que
estaban.

• Cada vez que sale un automóvil, los carros del extremo sur se mueven hacia adelante para
que, en toda ocasión, los espacios vacíos queden en el extremo sur.

• Escriba un programa en Java que procese un grupo de líneas de entrada, cada línea de
entrada contiene una E para llegada o una S para salida y un numero de placa.

• Se supone que los carros llegan y salen en el orden especificado en la entrada. El programa
debe imprimir un mensaje cada vez que llega o sale un auto.

• Cuando llega el carro debe especificar (el mensaje) si hay espacio o no para el mismo en el
estacionamiento. Si no hay espacio, el carro espera hasta que haya espacio o hasta que se lee
una línea de salida, cuando sale un carro, el mensaje debe incluir la cantidad de veces que se
Ejercicio Propuesto - Clase
Ejercicio Propuesto - Entregar
• Ver Archivo Ejercicio Listas Enlazadas Simples -Entregar
La Clase List en Java
Interface ArrayList
• Acceso posicional eficiente

• Inserción y extracción costosas menos en la última posición que es instantánea

• Cuando se supera el tamaño del array, se crea uno nuevo más grande y se copian en
él los elementos del antiguo

• Es una Lista implementada como un arreglo


Interface ArrayList
• De forma general un ArrayList en Java se crea de la siguiente forma:
ArrayList nombreArray = new ArrayList();

• Esta instrucción crea el ArrayList nombreArray vacío.

• Un arrayList declarado así puede contener objetos de cualquier tipo.

• Por ejemplo:
ArrayList a = new ArrayList();
a.add("Lenguaje");
a.add(3);
a.add('a');
a.add(23.5);

• Los elementos del arrayList a son:


“Lenguaje” 2 ‘a’ 23.5

• Es decir, un ArrayList puede contener objetos de tipos distintos.


Interface ArrayList
NOMBRE
PARÁMETROS DESCRIPCIÓN VALOR RETORNADO
MÉTODO
add Elemento a Añade un elemento a el ArrayList. Booleano, indicando el estado de
insertar. Añade desde el final. la operación.
remove Índice a borrar. Borra un elemento del ArrayList. Booleano, indicando el estado de
la operación.
clear Ninguno Limpia el ArrayList de elementos. Ninguno
size Ninguno Devuelve el número de elementos Cantidad de elementos en el
ArrayList
get Índice del elemento Devuelve el elemento en el índice Elemento en el índice indicado
queremos indicado

iterator Ninguno Devuelve un iterador para recorrer el Iterator


ArrayList.
isEmpty Ninguno Indica si el ArrayList esta o o vacia Booleano, indicando si esta vacio
o no el ArrayList.
indexOf Elemento Devuelve la posición del elemento Posición del elemento en el
puesto como parámetro. ArrayList.
Ejercicio Resuelto
• Uso de ArrayList para implementar colección de música (CDs)

• Puede implementar nuevos manejos de datos? como por ejemplo:


 Que nos muestre solo los Cds que valen mas de 20000
 Que nos muestre los Cds que tienen menos de n pistas solamente
 Eliminar los Cds que cuesten mas de X
Interface LinkedList
• Acceso posicional costoso

• Inserción y extracción costosas

• Menos en la primera y última posición que es inmediato

• Tamaño ilimitado
Interface LinkedList
• Lista doblemente enlazada
 La clase LinkedList implementa la interface List. Eso quiere decir que tendrá una
serie de métodos propios de esta interface y comunes a todas las
implementaciones. Así utilizando siempre que se pueda declaración de objetos del
tipo definido por la interface podemos cambiar de forma relativamente fácil su
implementación (por ejemplo pasar de ArrayList a LinkedList y viceversa) y
conseguir mejoras en el rendimiento de nuestros programas con poco esfuerzo.
 Ahora centrándonos en la clase LinkedList, ésta se basa en la implementación de
listas doblemente enlazadas. Esto quiere decir que la estructura es un poco más
compleja que la implementación con ArrayList
Interface LinkedList
• Metodos específicos de LinkedList
Ejercicio Propuesto
• Crear una clase denominada ListaMuertosGoT que al ser inicializada contenga
un LinkedList con tres Strings que sean personajes de GoT (Game of Thrones)
que ya hayan muerto en la serie.
• Crear una clase test con el método main que inicialice un objeto
ListaMuertosGoT, pida dos personaje muertos más al usuario, los añada a la
lista y muestre el contenido de la lista por pantalla
• Por cada personaje debe tenerse:
 Nombre
 Edad (aproximada) en que falleció
 Forma en que falleció

Advertencia: La adición de personajes debe funcionar de acuerdo al método


inserta()descrito antes

Ayuda: Aquí tiene un listado


https://www.elconfidencial.com/multimedia/album/cultura/2016-06-29/los-100-muertos-de-
juego-de-tronos-cual-te-dio-mas-pena_1224741#1

También podría gustarte