Deixe-me tentar esclarecer o algoritmo de detecção de ciclo fornecido em http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare em minhas próprias palavras.
Como funciona
Vamos ter uma tartaruga e uma lebre (nome dos ponteiros) apontando para o início da lista com um ciclo, como no diagrama acima.
Vamos supor que, se movermos a tartaruga 1 passo de cada vez e dermos 2 passos por vez, eles acabarão se encontrando em um ponto. Vamos mostrar que, em primeiro lugar, essa hipótese é verdadeira.
A figura ilustra uma lista com um ciclo. O ciclo tem uma duração de n
e estamos inicialmente a alguns m
passos do ciclo. Digamos também que o ponto de encontro está a alguns k
passos do início do ciclo e a tartaruga e a lebre se encontram quando a tartaruga toma i
medidas totais. (Hare já teria tomado todas 2i
as medidas até então).
As 2 condições a seguir devem ser mantidas:
1) i = m + p * n + k
2) 2i = m + q * n + k
O primeiro diz que a tartaruga move i
etapas e, nessas i
etapas, chega primeiro ao ciclo. Depois, percorre os p
tempos de ciclo para obter um número positivo p
. Finalmente, ele passa por k
mais nós até encontrar a lebre.
O mesmo vale para a lebre. Ele move 2i
etapas e, nessas 2i
etapas, chega primeiro ao ciclo. Depois, percorre os q
tempos de ciclo para obter um número positivo q
. Finalmente, ele passa por k
mais nós até encontrar a tartaruga.
Como a lebre viaja com o dobro da velocidade da tartaruga, e o tempo é constante para ambos quando atingem o ponto de encontro.
Então, usando simples relação de velocidade, tempo e distância,
2 ( m + p * n + k ) = m + q * n + k
=> 2m + 2pn + 2k = m + nq + k
=> m + k = ( q - 2p ) n
Entre m, n, k, p, q, os dois primeiros são propriedades da lista fornecida. Se pudermos mostrar que há pelo menos um conjunto de valores para k, q, p que torna essa equação verdadeira, mostramos que a hipótese está correta.
Um desses conjuntos de soluções é o seguinte:
p = 0
q = m
k = m n - m
Podemos verificar se esses valores funcionam da seguinte maneira:
m + k = ( q - 2p ) n
=> m + mn - m = ( m - 2*0) n
=> mn = mn.
Para este conjunto, i
é
i = m + p n + k
=> m + 0 * n + mn - m = mn.
Obviamente, você deve ver que isso não é necessariamente o menor possível. Em outras palavras, tartaruga e lebre podem já ter se encontrado antes muitas vezes. No entanto, como mostramos que eles se encontram em algum momento pelo menos uma vez, podemos dizer que a hipótese está correta. Então eles teriam que se encontrar se movermos um deles 1 passo, e o outro 2 passos por vez.
Agora podemos ir para a segunda parte do algoritmo, que é como encontrar o início do ciclo.
Início do ciclo
Quando a tartaruga e a lebre se encontrarem, vamos colocar a tartaruga de volta ao início da lista e manter a lebre onde eles se conheceram (que está a k passos do início do ciclo).
A hipótese é que, se permitirmos que eles se movam na mesma velocidade (1 passo para ambos), a primeira vez que eles se encontrarem novamente será o início do ciclo.
Vamos provar esta hipótese.
Vamos primeiro assumir que algum oráculo nos diz o que é m.
Então, se permitirmos que eles movam m + k passos, a tartaruga terá que chegar ao ponto que eles se encontraram originalmente (k se afasta do início do ciclo - veja na figura).
Anteriormente, mostramos isso m + k = (q - 2p) n
.
Como m + k passos é um múltiplo de duração do ciclo n, a lebre, nesse meio tempo, passaria pelos tempos do ciclo (q-2p) e retornaria ao mesmo ponto (k se afastaria do início do ciclo).
Agora, em vez de deixá-los mover m + k passos, se os deixássemos mover apenas m passos, a tartaruga chegaria ao início do ciclo. A lebre seria k passos antes de completar as rotações (q-2p). Desde que iniciou k etapas antes do início do ciclo, a lebre teria que chegar ao início do ciclo.
Como resultado, isso explica que eles teriam que se encontrar no início do ciclo após várias etapas pela primeira vez (primeira vez porque a tartaruga acabou de chegar ao ciclo após m etapas e ela nunca conseguia ver a lebre que já estava dentro). o ciclo).
Agora sabemos que o número de etapas necessárias para movê-las até que elas se encontrem acaba sendo a distância do início da lista ao início do ciclo, m. Obviamente, o algoritmo não precisa saber o que é m. Apenas moverá a tartaruga e a lebre um passo de cada vez até que se encontrem. O ponto de encontro deve ser o início do ciclo e o número de etapas deve ser a distância (m) do início do ciclo. Supondo que sabemos o comprimento da lista, também podemos calcular a duração do ciclo de subtração m do comprimento da lista.