Clase 5 Listas Abiertas

Descargar como ppsx, pdf o txt
Descargar como ppsx, pdf o txt
Está en la página 1de 15

ALGORITMOS Y ESTRUCTURA DE DATOS

DOCENTE:
RAMÓN TOALA DUEÑAS

CONTENIDO A TRATAR HOY:


Listas dinámicas – Listas abiertas.
Periodo: Noviembre 2020 a Marzo 2021
Retroalimentación:
Interrogantes de la clase anterior, el estudiante debe contestar estas
preguntas con sus propias palabras y ejemplos, subirlos al aula virtual
en el repositorio de actuaciones “Actuación de clase 8”:
1. ¿Qué es una bicola o cola doble?
2. ¿Qué es una cola doble con salida restringida?
3. ¿Cómo es el recorrido en una cola respetando la regla de “Nodo Procesado,
Nodo eliminado”?
4. ¿Cómo se define a una inserción al inicio?
5. ¿Cómo se define a una inserción al final?
6. ¿Qué es una Cola circular?
7. ¿Cómo funciona el amarre de un nuevo nodo en una cola circular?
8. ¿Cómo funciona la extracción de un Nodo en una cola circular?
Objetivos de la Clase:

 Entender como funciona una Lista Abierta y como aplicar sus reglas al
desarrollar los diferentes métodos en clases modelos.

 Desarrollar aplicaciones que permitan la gestión de datos utilizando Listas


Abiertas
Desarrollo de Listas Abiertas
En este tipo de estructura de datos, los elementos se encuentran ordenados de manera consecutiva, pueden ser insertados o extraídos desde
cualquier ubicación de la estructura.
Con la lista enlazada existe un nodo cabecera y todos los elementos de la lista tendrán un elemento previo, puesto que el previo del primer
elemento es la cabecera, el último de la lista tendrá como referencia null.
Una lista vacía corresponde a una cabecera cuya referencia tiene null.

cebecera

La estructura de almacenamiento de cada nodo de la lista es igual a la utilizada en las otras estructuras:
public class Nodo { // Métodos get y set para los atributos.
private int valor; // Variable o lista de variables para guardar datos. public int getValor() { Recuerde que
private Nodo sig; // Atributo para hacer referencia al nodo siguiente. return valor; los métodos
El atributo valor es un modelo que puede ser reemplazado por otros atributos, el } Get y Set
atributo Sig será quien almacene la referencia a la siguiente variable sin nombre, public void setValor(int valor) { sirven para
observe que este atributo es del mismo tipo de la clase Nodo this.valor = valor; extraer e
} insertar
// Métoso constructor que inicializamos el valor de las variables. public Nodo getSig() { valores a cada
public void Nodo(){ Recuerde que los métodos constructores sirven para return sig; atributo de la
this.valor = 0; inicializar los atributos, así valor tomará cero y Sig } clase porque
this.sig = null; tomará null que significa último de la estructura public void setSig(Nodo sig) { son privados
} this.sig = sig;
}
}
Desarrollo de Listas Abiertas
Una vez que se tiene la clase Nodo, se crea la clase Lista que podrá contener una diversidad de métodos de ingresos, recorridos y estracciones:
public class Lista { public void agregarAlFinal(int valor){
private Nodo cabecera; Nodo nuevo = new Nodo();
public void Lista(){ nuevo.setValor(valor);
cabecera = null; if (esVacia()) {
cabecera = nuevo; aux tomara la referencia de la primera variable
}
} else{ dinámica y llegará hasta la última de la lista (la
public boolean esVacia(){ que tiene null)
return cabecera == null; Nodo aux = cabecera;
Para recorrer toda la estructura
} // Recorre la lista hasta llegar al ultimo nodo
se utiliza la variable aux que
avanzará mientras la referencia while(aux.getSig() != null){
Este algoritmo es similar al utilizado por
la Pila porque agrega los nuevos nodos al sea diferente de null aux = aux.getSig (); Proceso de avanzar a la siguiente variable
principio de la lista, se considera el }
método de amarre más fácil. // Agrega el nuevo nodo al final de la lista.
public void agregarAlInicio(int valor){ aux.setSig(nuevo);
Nodo nuevo = new Nodo(); }
nuevo.setValor(valor); }
if (esVacia()) {
cabecera = nuevo;
} else{
// Une el nuevo nodo con la lista existente.
nuevo.setSig(cabecera);
// Renombra al nuevo nodo como el inicio de la lista.
cabecera = nuevo;
}
}
INSERCIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Esta posibilidad de inserción es igual a la utilizada por las listas con reglas Pila:

public void agregarAlInicio (int valor){ cabecera


Nodo nuevo = new Nodo(); null 10 4 17 3 11 2 8 1 23 null
nuevo.setValor(valor); 1
if (esVacia()) { 2
cabecera = nuevo; 3
4
}
5
else{
23, 8, 11, 17, 10
nuevo.setSig(cabecera);
cabecera = nuevo;
}
}
INSERCIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Esta posibilidad de inserción es igual a la utilizada por las listas con reglas Cola, se diferencia en que no utiliza un puntero fijo para insertar al final:

public void agregarAlFinal(int valor){ cabecera


Nodo nuevo = new Nodo(); 23 2 8 3 11 4 17 5 10 null
null
nuevo.setValor(valor); 1
if (esVacia()) {
cabecera = nuevo; aux aux aux aux
1 2 3 4
} else{
Nodo aux = cabecera;
// Recorre la lista hasta llegar al ultimo nodo 23, 8, 11, 17, 10
while(aux.getSig() != null){
aux = aux.getSig ();
}
// Agrega el nuevo nodo al final de la lista.
aux.setSig(nuevo);
}
Este algoritmo utiliza aux para recorrer los nodos y ubicarse en el último ingresado, empieza desde cabecera y
}
avanza mientras la referencia sea diferente de null, recuerde que cada vez que se crea una variable dinámica,
esta de inicializa con 0 para la variable valor y null para la variable sig. Por lo tanto la última variable siempre
tendrá null como referencia.
INSERCIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Este algoritmo sirve para verificar la existencia o no de un determinado valor en el lista:

public boolean buscar(int referencia){ referencia cabecera


23 2 8 3 11 4 17 5 10 null
Nodo aux = cabecera; 17 1
boolean encontrado = false;
// Recorrido de la lista hasta encontrar el elemento o el final aux aux aux aux
while(aux != null && encontrado != true){ 1 2 3 4
// Consulta si el valor del nodo es igual al de referencia.
if (referencia == aux.getValor()){
encontrado
encontrado = true;
false
}
true
else{
aux = aux.getSiguiente();
 El algoritmo utiliza una variable de estado (encontrado) que identifica si ya ha sido encontrada o
}
} no el valor de referencia
return encontrado;  La evaluación de repetición del control while indica que volverá a repetir mientras no haya
} llegado al final y no se lo ha encontrado, por esta razón la variable encontrado se inicializa con
false ya que, en caso de no encontrarlo mantendrá el valor y devolverá falso
 La condición interna verifica si existe el valor, caso contrario avanzará con el siguiente nodo
INSERCIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Esta posibilidad de inserción permite agregar un elemento después de un nodo que sirve de referencia:
Por ejemplo, se insertará el nodo con el valor 10 después del nodo con valor 8

public void insertarPorReferencia(int referencia, int valor){ referencia valor nuevo


Nodo nuevo = new Nodo(); 8 10 10 3
nuevo.setValor(valor);
if (!esVacia()) {
// Consulta si el valor existe en la lista. cabecera 23 2 8 35 11 4 17 null
if (buscar(referencia)) { 1
Nodo aux = cabecera;
// Recorre la lista hasta llegar al nodo de referencia. aux aux siguiente
1 2
while (aux.getValor() != referencia) { 3
aux = aux.getSig();
}  Este ejemplo utiliza el método buscar() que devuele verdadero si existe un
// Crea un respaldo de la continuación de la lista. determinado valor en la lista, o falso en caso de no existir
Nodo siguiente = aux.getSig();  Este algoritmo utiliza dos variables estáticas (aux y siguiente) de referencias
// Enlaza el nuevo nodo después del nodo de referencia. para insertar una variable dinámica entre los dos nodos.
aux.setSig(nuevo);  Este método es útil para agregar elementos en cualquier posición conociendo
// Une la continuacion de la lista al nuevo nodo. que se insertará después de la referencia enviada.
nuevo.setSig(siguiente);
}
}
}
INSERCIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Este algoritmo sirve para actualizar o modificar el contenido de una variable:
public void actualizarPorReferencia(int referencia, int valor){ referencia Valor
if (buscar(referencia)) { 11
Nodo aux = cabecera; 45
// Recorre la lista hasta llegar al nodo de referencia.
while(aux.getValor() != referencia){
cabecera
23 2 8 3 11
45 4 17 5 10 null
aux = aux.getSig(); 1
}
// Actualizamos el valor del nodo aux aux aux
aux.setValor(valor); 1 2 3
} El algoritmo realiza la actualización si el elemento existe en la lista, así que el recorrido se dar
} mientras el valor del nodo sea diferente del valor buscado.
El siguiente algoritmo sirve para mostrar la lista numerada de todos los elementos de esta estructura:
public void mostrarLista(){
if (!esVacia()) { cabecera
23 2 8 3 11 4 17 5 10 null
Nodo aux = cabecera; 1
int i = 0; // Posición de los elementos en la lista.
// Recorre la lista hasta el final. aux i aux aux aux aux
while(aux != null){ 1 2 3 4 5
0 null
System.out.print(i + ".[ " + aux.getValor() + " ]" + " -> "); 1
aux = aux.getSig(); 2
i++; 3
} 4
} 0.[23]-> 1.[8]-> 2.[11]-> 3.[17]-> 4.[10]->
5
}
Acceso y eliminación de una lista
La variable estática cabecera puede acceder a los contenidos de otras variables dinámicas aparte de la primera, es una característica de
todos los lenguajes de programación, esto se logra porque tiene la referencia a la primera variable dinámica y a su vez la primera tiene
referencia a la segunda y así sucesivamente hasta la última de la estructura
Por ejemplo, suponga que desea acceder al contenido de la las variables dinámicas de la siguiente estructura:

Cabecera
1

Por ejemplo, para acceder al valor y la dirección que cabecera.getValor(); //esto devuelve 11
contiene la primera variable dinámica se lo haría así: cabecera.getSig(); //esto devuelve 2

cabecera.getSig().getValor(); //esto devuelve 8


Por ejemplo, suponga que desea acceder al valor y la
dirección que contiene la segunda variable dinámica: getSig() devolverá la referencia de la segunda variable (2).
(2). getValor() devuelve el valor que tiene la variable 2 (8)
cabecera.getSig().getSig(); //esto devuelve 3
getSig() devolverá la referencia de la segunda variable (2).
(2). getSig() devuelve la referencia que tiene la variable 2 (3)
En Java una vez que una variable dinámica no se encuentra referenciada se elimina automáticamente
// Método elimina lista
public void eliminar(){
cabecera = null; null
}
ELIMINACIÓN DE ELEMENTOS EN UNA LISTA ABIERTA
Este algoritmo sirve para verificar la existencia o no de un determinado valor en el lista:
public void eliminarPorReferencia(int referencia){ referencia
if (buscar(referencia)) { 11
// Consulta si el nodo a eliminar es el primero
if (cabecera.getValor() == referencia) {
// El primer nodo apunta al siguiente. cabecera
cabecera = cabecera.getSig(); 23 2 8 35 11 4 17 5 10 null
1
} else{
Nodo aux = cabecera;
while(aux.getSig().getValor() != referencia){ aux aux siguiente
aux = aux.getSig(); 1 2 4
}
// Guarda el nodo siguiente del nodo a eliminar.
Nodo siguiente = aux.getSig().getSig();
aux.setSig(siguiente);
}
}
}  El algoritmo muestra la posibilidad de acceder a datos de variables dinámicas siguientes a la que se esta
referenciando
 La evaluación del recorrido en el control while indica que volverá a repetir mientras el valor de la siguiente variable
es diferente a la buscada
Estructura completa de la clase lista:
public class Lista { public boolean buscar(int referencia){ public void eliminarPorReferencia(int referencia){
private Nodo cabecera; Nodo aux = cabecera; if (buscar(referencia)) {
public void Lista(){ boolean encontrado = false; if (cabecera.getValor() == referencia) {
cabecera = null; while(aux != null && encontrado != true){ cabecera = cabecera.getSig();
} if (referencia == aux.getValor()){ } else{
public boolean esVacia(){ encontrado = true; Nodo aux = cabecera;
return cabecera == null; } else{ aux = aux.getSiguiente(); } while(aux.getSig().getValor() != referencia){
} } aux = aux.getSig();
public void agregarAlInicio(int valor){ return encontrado; }
Nodo nuevo = new Nodo(); } Nodo siguiente = aux.getSig().getSig();
nuevo.setValor(valor); public void actualizarPorReferencia(int referencia, int valor){ aux.setSig(siguiente);
if (esVacia()) { if (buscar(referencia)) { }
cabecera = nuevo; Nodo aux = cabecera; }
} else{ while(aux.getValor() != referencia){ }
nuevo.setSig(cabecera); aux = aux.getSig(); public void insertarPorReferencia(int referencia, int valor){
cabecera = nuevo; } } Nodo nuevo = new Nodo();
} aux.setValor(valor); nuevo.setValor(valor);
public void agregarAlFinal(int valor){ } if (!esVacia()) {
Nodo nuevo = new Nodo(); } if (buscar(referencia)) {
nuevo.setValor(valor); public void mostrarLista(){ Nodo aux = cabecera;
if (esVacia()) { if (!esVacia()) { while (aux.getValor() != referencia) {
cabecera = nuevo; Nodo aux = cabecera; aux = aux.getSig();
} else{ int i = 0; }
Nodo aux = cabecera; while(aux != null){ Nodo siguiente = aux.getSig();
while(aux.getSig() != null){ System.out.print(i + ".[ " + aux.getValor() + " ]" + " -> "); aux.setSig(nuevo);
aux = aux.getSig (); aux = aux.getSig(); nuevo.setSig(siguiente);
} i++; }
aux.setSig(nuevo); } }
} } }
} }
Estructura completa de la clase lista:
public class Main {
public static void main(String[] args) throws Exception {
Lista lista = new Lista(); Resultado que mostrará la ejecución:
System.out.println("<<-- Ejemplo de lista simple -->>\n");
lista.agregarAlFinal(12); <<-- Ejemplo de lista simple -->>
lista.agregarAlFinal(15); <<-- Lista -->> 0.[6]-> 1.[41]-> 2.[12]-> 3.[15]-> 4.[9]->
lista.agregarAlFinal(9); Inserta un nodo con valor 16 después del 15
lista.agregarAlInicio(41); 0.[6]-> 1.[41]-> 2.[12]-> 3.[15]-> 4.[16]-> 5.[9]->
lista.agregarAlInicio(6); Actualiza el valor 12 del tercer nodo por 13
System.out.println("<<-- Lista -->>"); 0.[6]-> 1.[41]-> 2.[13]-> 3.[15]-> 4.[16]-> 5.[9]->
lista.mostrarLista(); Elimina el nodo con el valor 41
System.out.println("\nInserta un nodo con valor 16 después del 15"); 0.[6]-> 1.[13]-> 2.[15]-> 3.[16]-> 4.[9]->
lista.insertarPorReferencia(15, 16); Elimina la lista
lista.mostrarLista(); Consulta si la lista está vacía
System.out.println("\nActualiza el valor 12 del tercer nodo por 13");
lista.actualizarPorReferencia(12, 13); <<-- Fin de ejemplo lista simple -->>
lista.mostrarLista();
System.out.println("\nElimina el nodo con el valor 41");
lista.eliminarPorReferencia(41);
lista.listar();
System.out.println("\nElimina la lista");
lista.eliminar();
System.out.println("\nConsulta si la lista está vacía");
System.out.println(lista.esVacia());
System.out.println("\n\n<<-- Fin de ejemplo lista simple -->>");
}
}
CONCLUSIONES
 Las listas abiertas es una estructura lineal que permite administrar grandes volúmenes de datos, no posee
reglas estrictas como las implementadas en las Pilas o en las Colas.
 Aunque no es una regla, la estructura del Nodo de una lista debe poseer en su definición al menos un dato
para contener como información y obligatoriamente una variable que contenga la referencia a otra variable
dinámica del mismo tipo de la estructura de la lista.
 Una lista se puede implementar varios métodos de inserción para agregar elementos en cualquier posición de
la lista y cualquier forma de extraer elementos insertado en la misma.
 Se puede acceder al valor y la dirección que contiene la segunda o tercera variable dinámica a la que
normalmente se esta referenciando como una estrategia de manipulación de las variables dinámicas.
 Se puede recorrer una lista utilizando una variable estática auxiliar, el proceso consistiría en recorrer mientras
se cumpla la condición que podría ser: no llegar al final (el ultimo nodo tiene null como referencia) o avanzar
mientras sea el valor sea diferente del buscado, etc.

También podría gustarte