algoritmo di rilevamento del ciclo di Floyd | Determinare il punto di partenza del ciclo

cs.stackexchange https://cs.stackexchange.com/questions/10360

  •  16-10-2019
  •  | 
  •  

Domanda

Sto cercando aiuto capire algoritmo di rilevamento ciclo di Floyd. Ho passato con la spiegazione su wikipedia ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Posso vedere come l'algoritmo rileva ciclo in O (n). Tuttavia, non sono in grado di visualizzare il fatto che una volta tartaruga e puntatori lepre incontrano per la prima volta, l'inizio del ciclo può essere determinata spostando tartaruga puntatore indietro per iniziare e poi si spostano sia tartaruga e passo uno lepre alla volta. Il punto in cui primo incontro è l'inizio del ciclo.

Qualcuno può aiutarmi, fornendo una spiegazione, si spera diverso da quello su wikipedia, come io sono in grado di capire / visualizzarla?

È stato utile?

Soluzione 3

Ho trovato la risposta su StackOverflow. Grazie se qualcuno era alla ricerca in questo per me. E per chi, come me, ha voluto una spiegazione, si prega di fare riferimento a: https://stackoverflow.com/questions/3952805/proof-of-detecting-the-start-of-cycle-in-linked-list la risposta scelta alla domanda, spiega tutto!

Altri suggerimenti

Si può fare riferimento a "Rilevazione inizio di un ciclo in lista concatenata" , ecco un estratto:

 entrare descrizione dell'immagine qui

distanza percorsa dal slowPointer prima della riunione $ = x + y $

distanza percorsa dal fastPointer prima della riunione $ = (x + y + z) + y $ = X + 2y + z

Da fastPointer viaggia con doppia la velocità di slowPointer e Ora è costante sia quando la portata del punto di incontro. Quindi, utilizzando la velocità semplice, il tempo e la distanza relazione (slowPointer viaggiato metà della distanza):

\ begin {* align} 2 * \ operatorname {dist} (\ text {} slowPointer) & = \ operatorname {dist} (\ text {} fastPointer) \\ 2 (x + y) & = x + 2y + z \\ 2x + 2y & = x + 2y + z \\ x = z & \ End {align *}

Quindi spostando slowPointer dell'inizio della lista collegata, e rendendo sia slowPointer e fastPointer spostare un nodo alla volta, hanno entrambi stessa distanza di copertura .

Si raggiungerà nel punto in cui i ciclo inizia nella lista collegata.

Ho visto la risposta accettata come prova anche altrove. Tuttavia, mentre la sua facile Grok, non è corretto. Che si rivela è

$ x = z $ (che è ovviamente sbagliato, e il diagramma solo rende plausibile dovuto al modo in cui è abbozzato).

Che cosa si vuole veramente dimostrare è (utilizzando le stesse variabili, come descritto nello schema nella risposta accettata sopra):

$ z = x \ mod \ (y + z) $

$ (y + z) $ è la lunghezza del loop, $ L $

così, quello che vogliamo dimostrare è:

$ z = x \ mod \ L $

O che z è congruente a x (modulo L)

Dopo la prova ha più senso per me:

Punto di incontro, $ M = x + y $

$ 2 (x + y) = M + kL $, dove $ k $ è una costante. In sostanza, la distanza percorsa dal puntatore veloce è $ x + y $, più un multiplo di lunghezza del loop, $ L $

$ x + y = kL $

$ x = KL - y $

L'equazione di cui sopra dimostra che $ x $ è uguale a un multiplo della lunghezza del ciclo, $ L $ meno $ y $. Quindi, se il puntatore si avvia velocemente al punto di incontro, $ M $ oa $ x + y $, allora finirà all'inizio del ciclo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a cs.stackexchange
scroll top