1 / 36

Listas. Otras implementaciones

Listas. Otras implementaciones. 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.

whitley
Download Presentation

Listas. Otras implementaciones

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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. Listas con cabecera y centinela. Concepto • 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

  5. cent cab 3 7 null Listas con cabecera y centinela. Modelo Cabecera Centinela • 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; } } Lista

  6. 3 7 Manipulación de listas con cabecera y centinela Cabecera 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. Lista anterior actual

  7. Listas con cabecera y centinela. Recorrido completo 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"); }

  8. Listas con cabecera y centinela. Terminación anticipada • 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). 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. 3 7 5 Inserción en listas con cabecera y centinela. • Modelo de funcionamiento. dato = 5 cent cab 5 actual actual anterior aux anterior

  10. Inserción en listas con cabecera y centinela. • Reducción significativa de la complejidad lógica respecto al tratamiento convencional. • Código: 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"); }

  11. 3 7 7 Eliminar un elemento en lista con cabecera y centinela. 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; } cent cab 7 actual actual actual anterior anterior

  12. Listas. Listas circulares (anillos)

  13. 1 3 5 7 ? Listas circulares. Concepto (I). • 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 Lista nombre inicio NodoLista

  14. 1 3 5 7 Listas circulares. Concepto (II). • 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 NodoLista Lista nombre inicio

  15. Listas circulares. Inserción: casuística. • 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)

  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. Listas circulares. Inserción: código (II). 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"); } }

  18. Listas circulares. Eliminación: casuística. • 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

  19. Listas circulares. Eliminación: código (I). 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 "); }

  20. Listas. Listas doblemente enlazadas

  21. 5 1 2 null null Listas doblemente enlazadas • Declaración de la clase: class NodoLista { int clave; NodoLista sig; NodoLista ant; NodoLista (int x) { clave = x; sig = null; ant = null; } } public class Lista { String nombre; NodoLista inicio; Lista () { inicio = null; nombre = null; } } NodoLista Lista nombre inicio • 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:

  22. Listas doblemente enlazadas. Inserción 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"); }

  23. Listas doblemente enlazadas. Eliminación 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; } }

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

  25. Listas densas sobre matrices. Conceptos. numNodos = 5 public class Lista { int [ ] matriz; final int N = 10; int numNodos; Lista () { matriz = new int [N]; numNodos = 0; } } • Constructor: • 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:

  26. 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"); } Ejemplo: mostrar el contenido.

  27. 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; } Ejemplo: buscar un elemento.

  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. 10 12 13 21 Listas enlazadas sobre matrices. • 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:

  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. Listas enlazadas sobre matrices. Recorrido completo. static void escribirLista (Lista lista) { int i = lista.matriz [0].clave; while (i != 0) { System.out.print (lista.matriz [i].clave+" "); i = lista.matriz [i].sig; } System.out.println (“FIN”); } Ejemplo: mostrar el contenido.

  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"); }

More Related