Los bucles pueden detectarse en una lista vinculada inspeccionando todos los elementos de la lista y guardando el elemento visto. Si el elemento actual ya ha sido visto, entonces tenemos un bucle.
La detección de ciclos se puede implementar usando un Conjunto como adición de un elemento o prueba si un elemento está en el conjunto. Están en O de 1. El ciclo se puede romper al guardar el nodo anterior, una vez que se detecte el siguiente Elemento anterior. apunta a nulo en lugar del elemento que se ha visto anteriormente. Esta implementación tiene el mejor rendimiento ya que el algoritmo está en O (n) donde n es el número de elementos en la lista.
import java.util.HashSet;
import java.util.Set;
public class InterviewLinkedListCycle {
public static boolean testLoopON( Node head, boolean removeCycle ){
// Input Validation
if( head == null )
throw new IllegalArgumentException( "Input cannot be null" );
//Processing.
Set<Integer> seen = new HashSet<Integer>();
// save the head
Node current = head;
// Save the previous node
Node previous = null;
// Loop on elements
while( current != null ) {
// Check for the cycle
if ( seen.contains( current.data ) ){
if( removeCycle ){
// Break the loop
previous.next = null;
}
// We have found a loop
return true;
}
seen.add( current.data );
previous = current;
current = current.next;
}
// No Loop found
return false;
}
public static void main(String[] argv) throws Exception {
InterviewLinkedListCycle t = new InterviewLinkedListCycle();
Node head = new Node(1);
Node current = head;
for( int i = 2; i < 10 ; i++ ){
current.next = new Node(i);
current = current.next;
}
long before = System.nanoTime();
boolean found = testLoopON( head, true );
long after = System.nanoTime();
System.out.println( "Loop found = " + found + " in " + (int)(after-before)/1000 + " \u00B5 seconds" );
// Create the Loop
current.next = head.next;
before = System.nanoTime();
found = testLoopON( head, true );
after = System.nanoTime();
System.out.println( "Loop found = " + found + " in " + (int)(after-before)/1000 + " \u00B5 seconds" );
}
}
class Node {
Node(Integer data){
this.data = data;
}
Integer data;
Node next;
}
Loop found = false in 34 \u00B5 seconds Loop found = true in 15 \u00B5 seconds
Este ejemplo ejecuta 2 llamadas una sin un bucle en la lista enlazada y otra con un bucle en la lista enlazada.