LinkedList en Java ejercicios — la reserva de la posición N, los socios repetidos y la cola partida por la mitad (con soluciones y chuletario)
En un simulacro del Examen 3 escribí eliminarDuplicados comparando con ==. Lo probé con nombres escritos en el main y funcionó a la primera. Las pruebas del profesor leían los nombres de un archivo y mi método no borró ni uno. Era la trampa de == con los String que vimos en la teoría, y la vas a ver con salida real en el fragmento 1 de «¿Qué falla aquí?».
Ya has visto la teoría y has practicado con tres programas de la biblioteca. Ahora te toca a ti. Tres ejercicios en tres niveles sobre la misma cola de reservas de la biblioteca de la facultad: leer la reserva de una posición y buscar la posición de un socio, quitar los socios repetidos sin colecciones y partir la cola por la mitad en un solo recorrido. Los tres atacan los errores que más puntos quitan en el examen de estructuras encadenadas: avanzar un nodo de más, comparar textos con == y olvidar un extremo.
Cómo usar este artículo: intenta cada ejercicio por tu cuenta; si llevas más de diez minutos atascado, abre la pista; antes de mirar la solución, haz «¿Qué falla aquí?», y pega tu código en Python Tutor (eligiendo Java) para ver las flechas. Al final tienes un cuestionario tipo examen y el chuletario del tema.
Los tres ejercicios usan el molde del examen: los mismos Node y ContainerBase de la teoría (con first protected) y tu clase con extends ContainerBase, que lleva su propio size e insertarDetras (el mismo de la teoría). Recuerda la norma: nada de arrays ni colecciones para guardar los datos; en las pruebas solo los usamos para preparar los nombres.
Tabla de Contenidos
LinkedList en Java ejercicios: nivel básico
Ejercicio 1: obtener la reserva de una posición y buscar a un socio
Escribe la clase ColaBuscable con dos métodos:
String obtener(int pos): el socio de esa posición, empezando en 0 por la cabeza. Si la posición no existe (negativa o mayor o igual quesize), devuelvenull.int indiceDe(String socio): la posición de la primera aparición del socio, o-1si no está. Tiene que funcionar aunque el texto sea otro objeto (new String("Marta")).
Con la cola vacía y después con Laura -> Pablo -> Marta -> Pablo, la salida tiene que ser:
Vacía: obtener(0) = null, indiceDe("Laura") = -1
➡Laura->Pablo->Marta->Pablo->null
obtener(0) = Laura, obtener(2) = Marta, obtener(3) = Pablo
obtener(4) = null, obtener(-1) = null
indiceDe("Pablo") = 1, indiceDe("Nora") = -1
indiceDe(new String("Marta")) = 2
En obtener, valida antes de moverte y después da pos saltos con un for. En indiceDe, recorre con el for de siempre llevando un contador y compara con equals. Si vuelves del bucle sin encontrarlo, -1.
LinkedList en Java ejercicios: nivel intermedio
Ejercicio 2: eliminar los socios repetidos sin colecciones
Hay socios que reservan el mismo libro dos y tres veces. Escribe la clase ColaSinRepetidos con int eliminarDuplicados(), que deje solo la primera aparición de cada socio, modificando la propia cola (sin crear otra), mantenga size correcto y devuelva cuántos ha borrado. Sin HashSet, sin ArrayList y sin arrays: el examen no los deja.
Salida esperada con estas cuatro colas:
➡Laura->Pablo->Laura->Marta->Pablo->Iván->Laura->null => ➡Laura->Pablo->Marta->Iván->null (borrados 3, size 4) ➡Ana->Nora->Iván->null => ➡Ana->Nora->Iván->null (borrados 0, size 3) ➡Marta->Marta->Marta->Marta->null => ➡Marta->null (borrados 3, size 1) ➡null => ➡null (borrados 0, size 0)
Sin un conjunto de «vistos», cada nodo tiene que buscar sus copias detrás de él. Dos bucles: el de fuera elige un nodo (actual) y el de dentro recorre lo que hay detrás con la técnica de «pararse en el anterior» de la práctica. La clave está en cuándo avanza anterior: si borras el siguiente, su nuevo siguiente todavía no lo has mirado. Prueba mentalmente con cuatro Martas seguidas. Y compara con equals.
LinkedList en Java ejercicios: desafío final
Ejercicio 3: partir la cola por la mitad en un solo recorrido
La biblioteca abre un segundo mostrador y quiere repartir la cola de reservas en dos: la primera mitad se queda en el mostrador de siempre y la segunda pasa al nuevo, en el mismo orden. Si la cola tiene un número impar de personas, la del medio se queda en el primero.
Escribe ColaPartible partirPorLaMitad(), que corte la propia cola y devuelva otra ColaPartible con la segunda mitad, con los dos size correctos. La condición del desafío: un solo recorrido y sin usar size para buscar la mitad, ni crear nodos nuevos.
Salida esperada:
➡Laura->Pablo->Marta->Iván->Nora->null => ➡Laura->Pablo->Marta->null (3) + ➡Iván->Nora->null (2) ➡Laura->Pablo->Marta->Iván->null => ➡Laura->Pablo->null (2) + ➡Marta->Iván->null (2) ➡Ana->null => ➡Ana->null (1) + ➡null (0) ➡null => ➡null (0) + ➡null (0)
Dos referencias que avanzan a distinta velocidad: lento da un salto por vuelta y rapido, dos. Cuando rapido llegue al final, lento estará en la mitad. Haz que rapido empiece un nodo por delante (first.next) y piensa con cuatro nodos dónde quieres que se pare lento: en el último de la primera mitad, porque es el que tiene que cortar su flecha.
¿Qué falla aquí?
Tres fragmentos con un error de los que caen en los exámenes. Predice qué imprime cada uno antes de leer la explicación.
Fragmento 1: los repetidos que no se van
eliminarDuplicados con una sola diferencia: compara con ==.
public int eliminarDuplicados() {
int borrados = 0;
for (Node actual = first; actual != null; actual = actual.next) {
Node anterior = actual; // buscamos copias de actual DETRÁS de él
while (anterior.next != null) {
if (anterior.next.value == actual.value) {
anterior.next = anterior.next.next; // saltamos la copia; anterior NO avanza
borrados++;
} else {
anterior = anterior.next;
}
}
}
size -= borrados;
return borrados;
}
La prueba mete los mismos tres nombres en dos colas: en una con los literales tal cual y en la otra con new String(s), como si llegaran de un archivo o del teclado:
public class PruebaMal {
public static void main(String[] args) {
ColaSinRepetidos escritos = new ColaSinRepetidos();
ColaSinRepetidos leidos = new ColaSinRepetidos();
for (String s : new String[] {"Laura", "Pablo", "Laura"}) {
escritos.insertarDetras(s); // literales: Java reutiliza el mismo objeto
leidos.insertarDetras(new String(s)); // como si llegaran de un archivo: objetos distintos
}
System.out.println("Escritos: borrados " + escritos.eliminarDuplicados() + " -> " + escritos);
System.out.println("Leídos: borrados " + leidos.eliminarDuplicados() + " -> " + leidos);
}
}
Escritos: borrados 1 -> ➡Laura->Pablo->null Leídos: borrados 0 -> ➡Laura->Pablo->Laura->null
Qué falla: == compara referencias. Los literales iguales que escribes en el código son el mismo objeto (Java los reutiliza), así que en la primera cola el truco «funciona». En la segunda, cada new String es un objeto distinto y == dice que Laura no es Laura: no se borra nada. Es justo mi simulacro: las pruebas no siempre usan literales. Arreglo: anterior.next.value.equals(actual.value).
Dar por bueno un método con == porque pasa tus pruebas. Pruébalo siempre con new String(...).
Fragmento 2: el contador que se queda corto
public int contar() {
int total = 0;
Node n = first;
while (n.next != null) { // MAL: se para ANTES del último
total++;
n = n.next;
}
return total;
}
Se prueba con Laura -> Pablo -> Marta y después con una cola vacía:
➡Laura->Pablo->Marta->null tiene 2 nodos
Exception in thread "main" java.lang.NullPointerException: Cannot read field "next" because "n" is null
at ColaContar.contar(ColaContar.java:12)
at PruebaContar.main(PruebaContar.java:9)
Qué falla: dos cosas, por la misma condición. while (n.next != null) se para en el último nodo sin contarlo: con tres nodos da 2. Y con la cola vacía, n ya es null antes de entrar, así que n.next lanza el NullPointerException de la línea 12 de ColaContar.java, la del while. Fíjate en que el mensaje de Java te dice exactamente qué era null: "n". Arreglo: while (n != null), que cuenta todos y con la cola vacía no entra.
Fragmento 3: la cola vacía que recuerda a alguien
El atender de la cola con first y last de la práctica, con una línea de menos:
public String atender() {
if (first == null) {
return null; // nadie a quien atender
}
String socio = first.value;
first = first.next;
size--;
return socio;
}
Se encola a Laura y a Pablo y se atiende a los dos:
Vacía: ➡null | primero null, último Pablo, size 0
Qué falla: al atender al último, first pasa a null pero last sigue apuntando a Pablo. La cola dice estar vacía (➡null, size 0) y a la vez tener un último. Hasta aquí solo miente; lo grave llega con el siguiente encolar: como first == null, pone el nuevo como primero y último y todo vuelve a cuadrar por casualidad. Pero si otro método tuyo usa last antes (por ejemplo, un verUltimo() en las pruebas del examen), falla la prueba. Arreglo: tras first = first.next;, if (first == null) last = null;.
Soluciones comentadas
Solución ejercicio 1
public String obtener(int pos) {
if (pos < 0 || pos >= size) { // validamos ANTES de movernos
return null;
}
Node actual = first;
for (int i = 0; i < pos; i++) { // pos saltos desde la cabeza
actual = actual.next;
}
return actual.value;
}
public int indiceDe(String socio) {
int pos = 0;
for (Node n = first; n != null; n = n.next) {
if (n.value.equals(socio)) {
return pos; // el primero que coincide
}
pos++;
}
return -1; // no está
}
obtener: la validación va antes del bucle porque, si no, con pos igual a size el último salto deja actual a null y actual.value lanza NullPointerException. Con pos negativa el for no daría ninguna vuelta y devolverías la cabeza, que es peor: un resultado falso sin error. Luego, pos saltos: para obtener(2), de Laura a Pablo (i = 0) y de Pablo a Marta (i = 1); con i = 2 el for termina y devolvemos Marta.
indiceDe: el contador pos avanza a la vez que n. El return dentro del bucle hace que devolvamos la primera aparición: con Pablo dos veces, sale 1, no 3. Y como comparamos con equals, new String("Marta") se encuentra en la posición 2.
| Vuelta | n | pos | ¿n.value.equals("Pablo")? |
|---|---|---|---|
| 1 | Laura | 0 | No |
| 2 | Pablo | 1 | Sí: devuelve 1 |
Un método que busca y puede no encontrar devuelve un valor «imposible» (-1 para posiciones, null para objetos). Es lo que hace indexOf en String y en las colecciones de Java.
Solución ejercicio 2
public int eliminarDuplicados() {
int borrados = 0;
for (Node actual = first; actual != null; actual = actual.next) {
Node anterior = actual; // buscamos copias de actual DETRÁS de él
while (anterior.next != null) {
if (anterior.next.value.equals(actual.value)) {
anterior.next = anterior.next.next; // saltamos la copia; anterior NO avanza
borrados++;
} else {
anterior = anterior.next;
}
}
}
size -= borrados;
return borrados;
}
El for de fuera recorre la cola con actual. Para cada socio, el while de dentro empieza con anterior = actual y mira siempre anterior.next: si es una copia, la saltamos y anterior no avanza; si no, avanza. Así, cuando actual llega a un nodo, todas sus copias de detrás ya se han ido, y el for sigue con nodos que son la primera aparición de su valor.
Traza con Marta -> Marta -> Marta -> Marta (actual en la primera Marta):
| Vuelta | anterior | anterior.next | ¿Copia? | Qué pasa |
|---|---|---|---|---|
| 1 | Marta 1 | Marta 2 | Sí | Marta 1 apunta a Marta 3, anterior quieto |
| 2 | Marta 1 | Marta 3 | Sí | Marta 1 apunta a Marta 4 |
| 3 | Marta 1 | Marta 4 | Sí | Marta 1 apunta a null |
| 4 | Marta 1 | null | — | Fin del while; el for pasa a null y termina |
Tres borrados y size 4 − 3 = 1, como en la salida. Con la primera cola, Laura borra sus dos copias, Pablo una y Marta e Iván ninguna: 2 + 1 = 3 borrados y 7 − 3 = 4 nodos.
¿Por qué O(n²)? Cada nodo recorre lo que tiene detrás. Con un HashSet de vistos sería O(n), pero el examen prohíbe las colecciones. Con colas de biblioteca de decenas de personas, da igual.
«buscar copias detrás de mí» es la misma idea que el eliminarTodos de la práctica, solo que el valor a borrar cambia en cada vuelta del for.
Solución ejercicio 3
public ColaPartible partirPorLaMitad() {
ColaPartible segunda = new ColaPartible();
if (first == null || first.next == null) { // 0 o 1 nodos: no hay segunda mitad
return segunda;
}
Node lento = first;
Node rapido = first.next;
while (rapido != null && rapido.next != null) {
lento = lento.next; // 1 salto
rapido = rapido.next.next; // 2 saltos
}
segunda.first = lento.next; // la segunda mitad empieza detrás de lento
lento.next = null; // cortamos la cadena
segunda.size = size / 2; // la primera se queda con el de más si es impar
size = size - segunda.size;
return segunda;
}
Casos especiales primero: con 0 o 1 nodos no hay segunda mitad, y el bucle no podría arrancar (first.next con first a null lanza NullPointerException). Devolvemos una cola vacía.
El bucle: rapido da dos saltos por cada uno de lento. Como empieza un nodo por delante, cuando rapido ya no puede dar dos saltos, lento está en el último de la primera mitad. Traza con cinco personas:
| Vuelta | lento | rapido | ¿Sigue? |
|---|---|---|---|
| Inicio | Laura | Pablo | rapido.next es Marta: sí |
| 1 | Pablo | Iván | rapido.next es Nora: sí |
| 2 | Marta | null | No |
lento se para en Marta: la segunda mitad empieza en Iván. Con cuatro, rapido acaba en Iván (cuyo next es null) y lento en Pablo: 2 + 2. Fíjate en el dibujo: el corte son dos líneas. Primero la nueva cola guarda lento.next y después lento.next = null corta la cadena (otra vez, primero guardar y después mover).
Los tamaños: la segunda mitad tiene size / 2 (división entera: 5 / 2 = 2) y la primera, el resto (5 − 2 = 3). No hace falta volver a contar.
¿Por qué segunda.first compila? first es protected y estamos dentro de ColaPartible, que hereda de ContainerBase: podemos tocar el first de otro objeto de nuestra misma clase.
Esta técnica de dos velocidades (la de la tortuga y la liebre) sirve también para encontrar el elemento del medio o detectar si una lista tiene un ciclo, que viste en los ejercicios de LinkedList en Python.
Cuestionario tipo examen
Once preguntas como las del examen de estructuras encadenadas de FP2. Contesta sin mirar el artículo y después revisa las explicaciones.
Completa cómo se guarda una lista enlazada en Java:
Cada nodo guarda un dato en value y una referencia al siguiente nodo en ____. La lista solo guarda el primer nodo, first, que vale ____ cuando está vacía. El último nodo de la cadena tiene next a null. Para que una subclase pueda usar first, en ContainerBase se declara ____.
Palabras:
- 0
- private
- null
- last
- protected
- size
- next
Solución
Cada nodo guarda un dato en value y una referencia al siguiente nodo en next. La lista solo guarda el primer nodo, first, que vale null cuando está vacía. El último nodo de la cadena tiene next a null. Para que una subclase pueda usar first, en ContainerBase se declara protected.
Un nodo no sabe en qué posición está: solo su dato y quién va detrás. La lista solo conoce la cabeza (first). Con private la subclase no podría tocar first (first has private access); con protected, sí.
¿Qué imprime este fragmento? Node tiene value y next públicos y un constructor que recibe el valor.
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
a.next = b;
b.next = c;
Node nuevo = new Node("X");
nuevo.next = a.next;
a.next = nuevo;
String s = "";
for (Node n = a; n != null; n = n.next) {
s += n.value;
}
System.out.println(s);Solución
Respuesta: AXBC
nuevo apunta primero al que iba detrás de a (B) y después a pasa a apuntar a nuevo: X se cuela entre A y B sin mover ningún nodo. El recorrido da A, X, B, C.
Indica si es verdadero o falso:
- Para comparar el texto de dos
Stringdentro de los nodos hay que usarequals, no==. - Insertar al principio de una lista enlazada obliga a mover todos los nodos una posición.
- Si la lista guarda
firstylast, insertar al final no necesita recorrerla. - En el examen de estructuras encadenadas se puede guardar los datos en un
ArrayListsi es más cómodo. n.next.valuelanzaNullPointerExceptionsin.nextesnull.
Solución
- V — Para comparar el texto de dos
Stringdentro de los nodos hay que usarequals, no==. - F — Insertar al principio de una lista enlazada obliga a mover todos los nodos una posición.
- V — Si la lista guarda
firstylast, insertar al final no necesita recorrerla. - F — En el examen de estructuras encadenadas se puede guardar los datos en un
ArrayListsi es más cómodo. - V —
n.next.valuelanzaNullPointerExceptionsin.nextesnull.
== pregunta si son el mismo objeto; dos textos iguales pueden ser objetos distintos (por ejemplo, si vienen de un archivo). Insertar delante solo cambia dos referencias. Con last se engancha detrás sin recorrer. Y en el examen las colecciones y los arrays están prohibidos para guardar los datos.
Ordena las instrucciones para insertar un nodo al principio de la lista:
nuevo.next = first;first = nuevo;size++;Node nuevo = new Node(dato);
Solución
Orden correcto:
Node nuevo = new Node(dato);nuevo.next = first;first = nuevo;size++;
Primero se crea el nodo, después se enlaza con la cabeza actual y solo entonces se mueve first. Si haces first = nuevo antes de nuevo.next = first, el nodo nuevo se apunta a sí mismo y el resto de la lista se pierde.
Este método quiere contar los nodos. ¿Qué devuelve con la lista A -> B -> C?
public int contar() {
int total = 0;
Node n = first;
while (n.next != null) {
total++;
n = n.next;
}
return total;
}- 2
- 3
- 4
- Lanza NullPointerException
Solución
Respuesta: 2
while (n.next != null) sirve para pararse EN el último (por ejemplo, para engancharle algo), no para recorrerlos todos. Aquí cuenta A y B y se para con n en C. Con la lista vacía, además, n.next lanzaría NullPointerException.
Al eliminar el primer nodo de una lista con first, last y size, ¿qué hay que hacer?
first = first.next;- Restar 1 a
size - Si la lista se queda vacía, poner
last = null - Recorrer la lista para mover los demás nodos
- Poner siempre
last = null
Solución
Respuesta: first = first.next; · Restar 1 a size · Si la lista se queda vacía, poner last = null
Basta con que la cabeza pase al segundo nodo. El caso que más se olvida es el de un solo nodo: si last no se pone a null, la lista vacía sigue «recordando» el nodo borrado.
Relaciona cada operación con su coste en una lista enlazada que solo guarda first:
| Insertar al principio | |
| Insertar al final | |
| Obtener el elemento de la posición i | |
| Saber si está vacía |
Definiciones:
- O(n²): dos bucles anidados
- O(log n): búsqueda binaria
- O(n): hay que llegar al último
- O(1): cambian dos referencias
- O(1): mirar si first es null
- O(n): hay que dar i saltos
Solución
- Insertar al principio → O(1): cambian dos referencias
- Insertar al final → O(n): hay que llegar al último
- Obtener el elemento de la posición i → O(n): hay que dar i saltos
- Saber si está vacía → O(1): mirar si first es null
En una lista enlazada lo barato es lo que pasa en la cabeza. Todo lo que dependa de una posición obliga a recorrer desde first. La búsqueda binaria no sirve: no se puede saltar directamente a la mitad.
cola contiene Laura -> Pablo -> Marta. ¿Qué imprime? (toString() de ContainerBase dibuja ➡A->B->null; escribe la respuesta sin la flecha del principio)
Node anterior = null;
Node actual = first;
while (actual != null) {
Node siguiente = actual.next;
actual.next = anterior;
anterior = actual;
actual = siguiente;
}
first = anterior;
System.out.println(this);Solución
Respuesta: Marta->Pablo->Laura->null
Es la inversión en el sitio: en cada vuelta la flecha de actual pasa a apuntar a anterior. Al final anterior es el antiguo último (Marta) y pasa a ser la cabeza.
En ContainerBase, first es private. ¿Qué pasa con una subclase que hace first = nuevo;?
- No compila:
first has private access in ContainerBase - Compila, pero
firstse queda a null - Funciona igual que con protected
- Crea un atributo first nuevo en la subclase
Solución
Respuesta: No compila: first has private access in ContainerBase
Por eso el ContainerBase del examen declara first como protected: es el atributo que vas a manejar desde tu clase hija.
Para eliminar un nodo que está en medio de la lista, ¿qué referencia hace falta?
- La del nodo anterior, para hacer
anterior.next = actual.next - Solo la del nodo que se borra
- La de
firsty nada más - Ninguna: se pone
actual = null
Solución
Respuesta: La del nodo anterior, para hacer anterior.next = actual.next
Borrar es saltarse un nodo: quien tiene que cambiar su flecha es el anterior. Igualar una variable a null no quita nada de la cadena.
¿Qué imprime este fragmento?
String a = "Pablo";
String b = new String("Pablo");
System.out.println((a == b) + " " + a.equals(b));Solución
Respuesta: false true
new String crea otro objeto con el mismo texto: == compara referencias (son distintas) y equals compara el contenido (es el mismo). En un eliminar con == ese Pablo no se encontraría nunca.
Míralo paso a paso en Python Tutor
Entra en Python Tutor, elige Java y pega esta versión del ejercicio 3 con la cola de cinco personas (en Python Tutor todo va en una clase, así que Node va dentro de Tutor):
public class Tutor {
static class Node {
String value;
Node next;
Node(String value) {
this.value = value;
}
}
public static void main(String[] args) {
Node first = new Node("Laura");
first.next = new Node("Pablo");
first.next.next = new Node("Marta");
first.next.next.next = new Node("Iván");
first.next.next.next.next = new Node("Nora");
Node lento = first;
Node rapido = first.next;
while (rapido != null && rapido.next != null) {
lento = lento.next;
rapido = rapido.next.next;
}
Node segunda = lento.next; // Iván
lento.next = null; // la primera mitad acaba en Marta
System.out.println(first.value + " ... " + lento.value + " | " + segunda.value + " ... " + segunda.next.value);
}
}
Salida:
Laura ... Marta | Iván ... Nora
Qué observar paso a paso:
- Tras las cinco líneas de
next, la cadena va de Laura a Nora y la flecha de Nora esnull. - Antes del bucle,
lentoapunta a Laura yrapidoa Pablo, un nodo por delante. - En cada vuelta, la flecha de
lentoavanza un nodo y la derapido, dos. Cuenta los saltos. - Cuando
rapidopasa anull,lentoestá en Marta, el tercero. - Tras
lento.next = null, Python Tutor dibuja dos cadenas separadas: Laura -> Pablo -> Marta y, aparte, Iván -> Nora, que sigue viva porquesegundala apunta.
Chuletario: LinkedList en Java
Lo esencial en 30 segundos: un Node guarda value y next; la lista solo guarda first (protected en ContainerBase) y tu clase hereda con extends. Para insertar, enlaza primero y mueve después. Para borrar, te paras en el anterior. Recorre con for (Node n = first; n != null; n = n.next); para pararte en el último, while (n.next != null). Compara textos con equals. Valida antes de avanzar y prueba siempre la lista vacía y la de un nodo.
| Quiero… | Código | Coste |
|---|---|---|
| Insertar delante | nuevo.next = first; first = nuevo; | O(1) |
Insertar detrás (solo first) | while (actual.next != null) actual = actual.next; y actual.next = nuevo; | O(n) |
Insertar detrás (con last) | last.next = nuevo; last = nuevo; | O(1) |
| Recorrer | for (Node n = first; n != null; n = n.next) | O(n) |
| Borrar la cabeza | first = first.next; (+ last = null si se vacía) | O(1) |
| Borrar otro | anterior.next = anterior.next.next; | O(n) |
| Posición N | Validar y for (int i = 0; i < pos; i++) actual = actual.next; | O(n) |
| Buscar un texto | n.value.equals(socio) | O(n) |
| Invertir en el sitio | siguiente = actual.next; actual.next = anterior; y avanzar | O(n), memoria O(1) |
| Partir por la mitad | lento 1 salto, rapido 2, cortar en lento | Un recorrido |
Plantillas de los ejercicios:
| Ejercicio | Patrón | Resultado con la cola de ejemplo |
|---|---|---|
obtener(2) | Validar + pos saltos | Marta |
indiceDe("Pablo") | Contador + equals + return dentro | 1 |
eliminarDuplicados() | Dos bucles + anterior quieto al borrar | Laura -> Pablo -> Marta -> Iván |
partirPorLaMitad() | Lento y rápido + corte | Laura -> Pablo -> Marta / Iván -> Nora |
| Síntoma | Causa probable |
|---|---|
NullPointerException: Cannot read field "next" because "n" is null | Has avanzado un nodo de más o no has validado la lista vacía |
first has private access in ContainerBase | first es private; en el examen va protected |
| No encuentra un texto que sí está | Comparas con == en lugar de equals |
| Quedan repetidos seguidos | anterior avanza también cuando borras |
| La lista se queda en un nodo | Has girado o cambiado una flecha antes de guardar el siguiente |
| La cola vacía tiene «último» | Falta last = null al atender al último |
| Un contador se queda corto en 1 | while (n.next != null) en lugar de while (n != null) |
Antes de entregar, pregúntate:
- ¿Funciona con la lista vacía y con un solo nodo?
- ¿Hay algún
.valueo.nextsobre algo que pueda sernull? - ¿He enlazado antes de mover en todos los cambios de referencias?
- ¿Siguen
size(ylast, si lo tengo) diciendo la verdad después de mi método? - ¿He comparado los textos con
equals?
¿Te ha servido este artículo? Así puedes apoyar SergioLearns →




Qué es un sistema operativo — teoría con tu portátil en una tarde de estudio, una llamada a write() y la CPU que nunca descansa (y los tres programas que no se ejecutaban a la vez)