La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Listas. Otras implementaciones. Otras implementaciones. Listas con cabecera y centinela. Recorrido completo. Buscar un elemento. Insertar un elemento.

Presentaciones similares


Presentación del tema: "Listas. Otras implementaciones. Otras implementaciones. Listas con cabecera y centinela. Recorrido completo. Buscar un elemento. Insertar un elemento."— Transcripción de la presentación:

1 Listas. Otras implementaciones

2 Otras implementaciones. Listas con cabecera y centinela. Recorrido completo. Buscar un elemento. Insertar un elemento. Eliminar un elemento. Listas circulares (anillos). Insertar un elemento. Eliminar un elemento. Listas doblemente enlazadas. Insertar un elemento. Eliminar un elemento. Implementación de listas sobre estructuras estáticas (matrices). Listas densas. Buscar un elemento. Insertar un elemento. Eliminar un elemento. Recorrido completo. Listas enlazadas. Buscar un elemento. Insertar un elemento. Eliminar un elemento. Recorrido completo.

3 Listas. Listas con cabecera y centinela.

4 Mejora en la lógica de listas calificadas ordenadas con un tratamiento iterativo Casos especiales al implementar las operaciones Uso de nodos auxiliares para tratar elementos terminales: centinela y cabecera Cabecera permite: Tratar de forma no excepcional el primer elemento de una lista. Mismo tratamiento cuando la lista es vacía Centinela permite: Simplificar las condiciones de finalización de la búsqueda Listas con cabecera y centinela. Concepto

5 Listas con cabecera y centinela. Modelo Los nodos apuntados por los punteros cabecera (cab) y centinela (cent) son nodos falsos, sin contenido Clase Lista: Referencia a una estructura constituida por sendas referencias a nodos de la Lista class Lista { NodoLista cab,cent; Lista () { cab = new NodoLista (); cent = new NodoLista (); cab.sig = cent; } 37 Lista Cabecera Centinela cent cab null

6 37 Lista Cabecera Centinela anterioractual Manipulación de listas con cabecera y centinela Uso de referencias [anterior y] actual El proceso de búsqueda comienza con [la referencia anterior en la cabecera y] la referencia actual en el primer elemento real de la lista.

7 static void mostrarContenido (Lista lista) { NodoLista actual; actual= lista.cab.sig; while (actual != lista.cent) { System.out.print (actual.clave + " "); actual= actual.sig; } System.out.println (" FIN"); } Listas con cabecera y centinela. Recorrido completo

8 Simplificación de la lógica de búsqueda: se guarda el dato a buscar en la centinela (el dato siempre está fisicamente en la lista). Listas con cabecera y centinela. Terminación anticipada public boolean buscar (int dato) { NodoLista anterior,actual; boolean resul = false; anterior = cab; actual = anterior.sig; cent.clave = dato; while (actual.clave < dato) { anterior = actual; actual = actual.sig; } if ((actual != cent) && (actual.clave == dato)) resul = true; return resul; }

9 37 cent cab anterior actual dato = 5 5 anterior actual 5 aux Inserción en listas con cabecera y centinela. Modelo de funcionamiento.

10 Inserción en listas con cabecera y centinela. public void insertar (int dato) { NodoLista anterior, actual, aux; anterior = cab; actual = anterior.sig; cent.clave = dato; while (actual.clave < dato) { anterior = actual; actual = actual.sig; } if ((actual.clave > dato) || (actual == cent)) { aux = new NodoLista (dato); aux.sig = actual; anterior.sig = aux; } else System.out.println ("Error, el elemento está repetido"); } Reducción significativa de la complejidad lógica respecto al tratamiento convencional. Código:

11 public void eliminar (int dato) { NodoLista anterior,actual; anterior = cab; actual = anterior.sig; cent.clave = dato; while (actual.clave < dato) { anterior = actual; actual = actual.sig; } if ((actual == cent) || (actual.clave < dato)) System.out.println ("Error, elemento inexistente"); else anterior.sig = actual.sig; } Eliminar un elemento en lista con cabecera y centinela. 37 cent cab anterior actual 7 anterior actual 7

12 Listas. Listas circulares (anillos)

13 El último elemento de la lista tiene un enlace al primer nodo de ella. En principio, el puntero de referencia inicio podría apuntar a cualquier elemento de la lista. Importante no perderlo Desde un punto de vista lógico, el puntero inicio ha de permitir determinar la finalización del recorrido iterativo o recursivo Listas circulares. Concepto (I) ? Lista nombre inicio NodoLista

14 Puntero inicio: ¿apunta al primer o al último elemento? Si apunta al primer elemento: Acceso inmediato al primer elemento, pero hay recorrer la lista completa para llegar al último Si apunta al último elemento: Acceso inmediato al último elemento y al primero mediante lista.inicio.sig Lista nombre inicio NodoLista Listas circulares. Concepto (II).

15 Hay que tener en cuenta tres casos distintos: La lista está vacía: Insertar el nodo y enlazar consigo mismo Se inserta al final: Insertar el nodo y cambiar el puntero inicio. Insertar en cualquier otra posición. Para desarrollar los algortimos de insercióny eliminación, consideraremos que la referencia contenida en la lista apunta al último elemento de la lista (y en vez de inicio se denominará ultimo) Listas circulares. Inserción: casuística.

16 Listas circulares. Inserción: código (I). public void insertarCircular (int dato) { NodoLista aux, actual, anterior; if (ultimo == null) { aux = new NodoLista (dato); ultimo = aux; aux.sig = ultimo; } else { anterior = ultimo; actual = ultimo.sig; while ((actual.clave < dato) && (actual != ultimo)) { anterior = actual; actual = actual.sig; }

17 if (actual.clave != dato) { aux = new NodoLista (dato); if ((actual != ultimo) || (actual.clave > dato)) { aux.sig = actual; anterior.sig = aux; } else if (actual.clave < dato) { aux.sig = actual.sig; actual.sig = aux; ultimo= aux; } else System.out.println ("Error, el elemento ya existe"); } Listas circulares. Inserción: código (II).

18 Se presentan tres situaciones: La lista sólo tiene un nodo y se desea borrar Se va a borrar el nodo final: hay que actualizar el nodo inicio. Se va a borrar cualquier otro elemento Listas circulares. Eliminación: casuística.

19 static void eliminar (int x){ NodoLista anterior, actual; if (ultimo != null) { anterior = ultimo; actual = anterior.sig; while (actual != ultimo && actual.clave < x) { anterior = actual; actual = actual.sig; } if (actual.clave == x) { anterior.sig = actual.sig; if (ultimo == actual) if (ultimo != anterior) ultimo = anterior; else ultimo = null; } else System.out.println ("No existe el nodo de clave + x); } else System.out.println ("La lista está vacía "); } Listas circulares. Eliminación: código (I).

20 Listas. Listas doblemente enlazadas

21 Concepto: La lista se puede recorrer en ambos sentidos. El elemento anterior al primero será el elemento nulo. El elemento siguiente al último será el elemento nulo. Modelo: 5 null 1 2 Listas doblemente enlazadas Lista nombre inicio NodoLista public class Lista { String nombre; NodoLista inicio; Lista () { inicio = null; nombre = null; } Declaración de la clase: class NodoLista { int clave; NodoLista sig; NodoLista ant; NodoLista (int x) { clave = x; sig = null; ant = null; }

22 public void insertar (int clave) { NodoLista anterior = inicio, actual = inicio, nuevo; boolean encontrado = false; while ((actual != null) && !encontrado) if (actual.clave < clave) { anterior = actual; actual = actual.sig; } else encontrado = true; if (actual == null) { nuevo = new NodoLista (clave); if (inicio == null) inicio = nuevo; else { nuevo.ant = anterior; anterior.sig = nuevo; } else if (actual.clave > clave) { nuevo = new NodoListaDobleEnlace(clave); nuevo.sig = actual; nuevo.ant = actual.ant; actual.ant = nuevo; if (inicio != actual) anterior.sig = nuevo; else inicio = nuevo; } else System.out.println("error, la clave ya existe"); } Listas doblemente enlazadas. Inserción

23 public void eliminar (int dato) { NodoLista anterior = inicio, actual = inicio; boolean encontrado = false; while ((actual != null) && !encontrado) if (actual.clave < dato) { anterior = actual; actual = actual.sig; } else encontrado = true; if (actual == null) System.out.println("Error, el elemento no existe"); else if (actual.clave > dato) System.out.println("Error, el elemento no existe"); else if (inicio == actual) { inicio = lista.inicio.sig; inicio.ant = null; } else { anterior.sig = actual.sig; actual.sig.ant = anterior; } Listas doblemente enlazadas. Eliminación

24 Listas. Implementación de listas sobre estructuras estáticas (matrices).

25 Conceptos: El soporte físico de la lista es una matriz. Los elementos de la lista ocupan posiciones contiguas al principio de la matriz (el resto, si existe, es basura). Se requieren, aparte del propio contenido de la lista, dos informaciones: El número máximo de elementos que se define a priori: constante N. El número actual de elementos de la lista: variable numNodos. Modelo: Listas densas sobre matrices. Conceptos numNodos = 5 Constructor : public class Lista { int [ ] matriz; final int N = 10; int numNodos; Lista () { matriz = new int [N]; numNodos = 0; }

26 Ejemplo: mostrar el contenido. Listas densas sobre matrices. Recorrido completo. static void escribirLista (Lista lista) { for (int i = 0; i < lista.numNodos; i++) System.out.print (lista.matriz [i]+" "); System.out.println ("FIN"); }

27 Ejemplo: buscar un elemento. Listas densas sobre matrices. Terminación anticipada. public boolean busqueda (int dato) { boolean resul = false; if (numNodos != 0) resul = busqueda (0, dato); return resul; } private boolean busqueda (int i, int dato) { boolean resul = false; if (i < numNodos) if (matriz [i] < dato) resul = busqueda (i + 1, dato); else if (matriz [i] == dato) resul = true; return resul; }

28 Listas densas sobre matrices. Insertar un elemento. public void insertar (int dato) { if (numNodos < lista.N) insertar (0, dato); else System.out.println ("Error, la lista está llena"); } private void insertar (int i, int dato) { if (i == numNodos) { matriz [numNodos] = dato; numNodos++; } else if (matriz [i] < dato) insertar (i + 1, dato); else if (matriz [i] > dato) { for (int j = numNodos; j > i; j--) matriz [j] = matriz [j - 1]; matriz [i] = dato; numNodos++; } else System.out.println ("Error, la clave ya existe"); }

29 Listas densas sobre matrices. Eliminar un elemento. public void eliminar (int dato) { if (numNodos != 0) eliminar (0, dato); else System.out.println ("la lista está vacía"); } private void eliminar (int i, int dato) { if (i < numNodos) if (matriz[i] < dato) eliminar (i+1, dato); else if (matriz [i] > dato) System.out.println ("la clave no existe"); else { for (int j = i; j < numNodos-1; j++) matriz [j] = matriz [j+1]; numNodos--; }

30 Conceptos: El soporte físico de la lista es una matriz (array). Cada elemento de la matriz contiene una estructura (objeto) de la clase NodoListaSobreMatrizEnlazada con dos variables miembro: clave: es el propio valor de la lista. sig: es un puntero al siguiente elemento de la lista. Consideraciones particulares: El puntero (sig) del elemento de índice 0 referencia al primer elemento de la lista. Su variable clave no tiene ningún significado. El valor sig = 0 debe entenderse como puntero nulo (fin de la lista). Modelo: Listas enlazadas sobre matrices clave sig

31 Listas enlazadas sobre matrices. Constructores. class NodoLista { int clave, sig; NodoLista () { clave = 0; sig = 0; } public class Lista { final int NULL = 0, N = 9; NodoLista [] matriz; Lista () { int i; matriz = new NodoLista [N]; for (i = 0; i < N-1; i++) { matriz [i] = new NodoLista (); matriz [i].sig = i + 1; } matriz [i] = new NodoLista (); }

32 Ejemplo: mostrar el contenido. Listas enlazadas sobre matrices. Recorrido completo. static void escribirLista (Lista lista) { inti = lista.matriz [0].clave; while (i != 0) { System.out.print (lista.matriz [i].clave+" "); i = lista.matriz [i].sig; } System.out.println (FIN); }

33 Listas enlazadas sobre matrices. Buscar un elemento. public boolean busqueda (int dato) { boolean resul = false; int pos = matriz [0].clave; if (pos != 0) resul = buscar (pos, dato); return resul; } private boolean buscar (int pos, int dato) { boolean resul = false; if (matriz [pos].clave < dato) { if (matriz [pos].sig != 0) resul = buscar (matriz [pos].sig, dato); } else if (matriz [pos].clave == dato) resul = true; return resul; }

34 Listas enlazadas sobre matrices. Insertar un elemento (I). public void insertar (int dato) { if (matriz [0].sig != NULL) { int pos = matriz [0].clave; if (pos != 0) insertar (matriz [0].clave, 0, dato); else inser (0, 0, dato); } else System.out.println ("lista llena"); } private void insertar (int pos, int ant, int dato) { if (matriz [pos].clave < dato) if (matriz [pos].sig != 0) insertar (matriz [pos].sig, pos, dato); else inser (0, pos, dato); else if (matriz [pos].clave > dato) inser (pos, ant, dato); else System.out.println ("la clave ya existe"); }

35 Listas enlazadas sobre matrices. Insertar un elemento (y II). private void inser (int pos, int ant, int dato) { int nuevo = matriz [0].sig; matriz [0].sig = matriz [nuevo].sig; matriz [nuevo].clave = dato; if (ant != 0) { matriz [nuevo].sig = pos; matriz [ant].sig = nuevo; } else { int sig = matriz [0].clave; matriz [0].clave = nuevo; if (pos == 0) matriz [nuevo].sig = 0; else matriz [nuevo].sig = sig; }

36 Listas enlazadas sobre matrices. Eliminar un elemento. public void eliminar (int d) { int ant, pos, posAnt = 0; if (matriz [0].clave != NULL) { pos = matriz [0].clave; ant = matriz [pos].clave; while (ant < d) { posAnt = pos; pos = matriz [pos].sig; ant = matriz [pos].clave; } if (ant == d) { if (pos == matriz [0].clave) matriz [0].clave = matriz [pos].sig; else matriz [posAnt].sig = matriz[pos].sig; matriz [pos].sig = matriz [0].sig; matriz [0].sig = pos; } else System.out.println ("La clave no existe"); } else System.out.println ("Error. La lista está vacía"); }


Descargar ppt "Listas. Otras implementaciones. Otras implementaciones. Listas con cabecera y centinela. Recorrido completo. Buscar un elemento. Insertar un elemento."

Presentaciones similares


Anuncios Google