Floyd'un Döngüsü algılama algoritması | Döngünün başlangıç ​​noktasını belirleme


32

Floyd'un döngü algılama algoritmasını anlama konusunda yardım arıyorum. Wikipedia'daki açıklamayı okudum ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Algoritmanın O (n) zamanında çevrimi nasıl tespit ettiğini görebiliyorum. Bununla birlikte, kaplumbağa ve tavşan işaretçileri ilk defa bir araya geldiğinde, döngünün başlangıcının, bir anda bir adım olarak hem kaplumbağa hem de tavşanı hareket ettirmek üzere kaplumbağa işaretçisini geri hareket ettirerek belirlenebildiğini belirleyemiyorum. İlk buluştukları nokta, döngünün başlangıcıdır.

Birisi anlayamadığım / görselleştiremediğim için, umarım wikipedia'daki olandan farklı bir açıklama yaparak yardımcı olabilir mi?


3
Cevabı stackoverflow'ta buldum. Birisi benim için bu araştıran varsa teşekkürler. Ve benden hoşlananlar için bir açıklamada bulunmak isteyin, lütfen bakınız: stackoverflow.com/questions/3952805/… Soruya seçilen cevap, açıklar!
Anurag Kapur

Merhaba @Anurag. Bilginiz olsun, ben "Tortoise ve Hare" algoritma üzerinde bir blog yazısı yaptık burada
Kyle

fastDeğişkenin veya "tavşan" ın neden sadece bir ileriden ziyade, kaplumbağa olarak iki kat hızda hareket etmesi gerektiğini biliyor musunuz ?
devdropper87

Yanıtlar:


47

"Tek tek bağlı listedeki bir döngü başlangıcını algılama" konusuna bakın : İşte bir alıntı:

enter image description here

slowPointerToplantıdan önce kat edilen mesafe =x+y

fastPointerToplantıdan önce kat edilen mesafe =(x+y+z)+y = x + 2y + z

Yana fastPointerolan seyahatler çift hızı slowPointerve zaman sabittir hem zaman ulaşmak buluşma noktası için. Yani basit hız, zaman ve mesafe ilişkisini kullanarak ( slowPointermesafenin yarısı kadar gitti):

2dist(slowPointer)=dist(fastPointer)2(x+y)=x+2y+z2x+2y=x+2y+zx=z

Bu nedenle hareketli slowPointerbağlantılı liste başlatmak için, ve her ikisi de yapım slowPointerve fastPointerher seferinde bir düğüm hareket ettirmek için, her ikisi de kapağa aynı mesafeye sahip .

Bağlantılı listede döngünün başladığı noktada ulaşırlar.


2
Burada bir dönüşten sonra buluşacaklarını varsaydınız. Belli bir sayıdan sonra bir araya gelebilecekleri durumlar (çevrimin küçük olduğu yerlerde) olabilir. dönme
Navjot Waraich

1
@JotWaraich görüntü tüm vakaları temsil etmemektedir; Ancak mantık hala duruyor
denis631

3
bu, İnternet'teki bu algoritma hakkında en basit cevaptır
Marshall X

7

Kabul edilen cevabı başka yerlerde de kanıt olarak gördüm. Ancak, grok kolay, yanlıştır. Kanıtladığı şey

x=z (which is obviously wrong, and the diagram just makes it seem plausible due to the way it is sketched).

What you really want to prove is (using the same variables as described in the diagram in the accepted answer above):

z=x mod (y+z)

(y+z) is the loop length, L

so, what we want to prove is:

z=x mod L

Or that z is congruent to x (modulo L)

Following proof makes more sense to me:

Meeting point, M=x+y

2(x+y)=M+kL, where k is some constant. Basically, distance travelled by the fast pointer is x+y plus some multiple of loop length, L

x+y=kL

x=kLy

The above equation proves that x is the same as some multiple of loop length, L minus y. So, if the fast pointer starts at the meeting point, M or at x+y, then it will end up at the start of the loop.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.