Lassen Sie mich versuchen, den unter http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare bereitgestellten Zykluserkennungsalgorithmus in meinen eigenen Worten zu erläutern .
Wie es funktioniert
Lassen Sie uns eine Schildkröte und einen Hasen (Name der Zeiger) mit einem Zyklus auf den Anfang der Liste zeigen, wie in der obigen Abbildung.
Nehmen wir an, wenn wir die Schildkröte Schritt für Schritt bewegen und 2 Schritte gleichzeitig Hase, treffen sie sich schließlich zu einem bestimmten Zeitpunkt. Lassen Sie uns zeigen, dass zuallererst diese Hypothese wahr ist.
Die Abbildung zeigt eine Liste mit einem Zyklus. Der Zyklus hat eine Länge von n
und wir sind zunächst m
Schritte vom Zyklus entfernt. Nehmen wir auch an, der Treffpunkt ist nur k
wenige Schritte vom Beginn des Zyklus entfernt und Schildkröte und Hase treffen sich, wenn die Schildkröte i
insgesamt Schritte unternommen hat. (Hare hätte bis dahin 2i
insgesamt Schritte unternommen.)
Die folgenden 2 Bedingungen müssen gelten:
1) i = m + p * n + k
2) 2i = m + q * n + k
Der erste sagt, dass die Schildkröte i
Schritte bewegt und in diesen i
Schritten zuerst zum Zyklus gelangt. Dann durchläuft es die Zykluszeiten p
für eine positive Zahl p
. Schließlich geht es über k
mehr Knoten, bis es auf Hasen trifft.
Ähnliches gilt für Hasen. Es bewegt 2i
Schritte und in diesen 2i
Schritten gelangt es zuerst zum Zyklus. Dann durchläuft es die Zykluszeiten q
für eine positive Zahl q
. Schließlich geht es über k
weitere Knoten, bis es auf Schildkröte trifft.
Da Hase mit der doppelten Geschwindigkeit der Schildkröte reist und die Zeit für beide konstant ist, wenn sie den Treffpunkt erreichen.
Durch die Verwendung einer einfachen Geschwindigkeits-, Zeit- und Entfernungsbeziehung
2 ( m + p * n + k ) = m + q * n + k
=> 2m + 2pn + 2k = m + nq + k
=> m + k = ( q - 2p ) n
Unter m, n, k, p, q sind die ersten beiden Eigenschaften der gegebenen Liste. Wenn wir zeigen können, dass es mindestens einen Satz von Werten für k, q, p gibt, der diese Gleichung wahr macht, zeigen wir, dass die Hypothese korrekt ist.
Ein solcher Lösungssatz lautet wie folgt:
p = 0
q = m
k = m n - m
Wir können überprüfen, ob diese Werte wie folgt funktionieren:
m + k = ( q - 2p ) n
=> m + mn - m = ( m - 2*0) n
=> mn = mn.
Für dieses Set i
ist
i = m + p n + k
=> m + 0 * n + mn - m = mn.
Natürlich sollten Sie sehen, dass dies nicht unbedingt das kleinstmögliche ist. Mit anderen Worten, Schildkröte und Hase haben sich vielleicht schon oft getroffen. Da wir jedoch zeigen, dass sie sich mindestens einmal treffen, können wir sagen, dass die Hypothese richtig ist. Sie müssten sich also treffen, wenn wir einen von ihnen um einen Schritt und den anderen um zwei Schritte gleichzeitig bewegen würden.
Nun können wir zum zweiten Teil des Algorithmus übergehen, in dem der Beginn des Zyklus ermittelt wird.
Zyklusbeginn
Sobald sich Schildkröte und Hase treffen, setzen wir die Schildkröte wieder an den Anfang der Liste und halten den Hasen dort, wo sie sich getroffen haben (was k Schritte vom Zyklusbeginn entfernt ist).
Die Hypothese ist, dass, wenn wir sie mit der gleichen Geschwindigkeit bewegen lassen (1 Schritt für beide), das erste Mal, dass sie sich wieder treffen, der Zyklus beginnt.
Lassen Sie uns diese Hypothese beweisen.
Nehmen wir zunächst an, ein Orakel sagt uns, was m ist.
Wenn wir sie dann m + k Schritte bewegen lassen, müsste die Schildkröte an dem Punkt ankommen, an dem sie sich ursprünglich getroffen haben (k Schritte vom Zyklusbeginn entfernt - siehe Abbildung).
Zuvor haben wir das gezeigt m + k = (q - 2p) n
.
Da m + k Schritte ein Vielfaches der Zykluslänge n sind, würde Hase in der Zwischenzeit die Zykluszeiten (q-2p) durchlaufen und zum gleichen Punkt zurückkehren (k Schritte vom Zyklusbeginn entfernt).
Anstatt sie m + k Schritte bewegen zu lassen, würde die Schildkröte am Zyklusbeginn ankommen, wenn wir sie nur m Schritte bewegen lassen. Hase wäre k Schritte vor dem Abschluss von (q-2p) Rotationen. Da es k Schritte vor dem Zyklusbeginn begann, musste der Hase am Zyklusbeginn ankommen.
Dies erklärt, dass sie sich zum ersten Mal nach einigen Schritten zu Beginn des Zyklus treffen müssten (zum ersten Mal, weil die Schildkröte erst nach m Schritten im Zyklus ankam und nie einen Hasen sehen konnte, der sich bereits darin befand der Kreislauf).
Jetzt wissen wir, dass die Anzahl der Schritte, die wir benötigen, um sie zu bewegen, bis sie sich treffen, die Entfernung vom Anfang der Liste bis zum Beginn des Zyklus ist, m. Natürlich muss der Algorithmus nicht wissen, was m ist. Es bewegt nur Schildkröte und Hase Schritt für Schritt, bis sie sich treffen. Der Treffpunkt muss der Zyklusstart sein und die Anzahl der Schritte muss der Abstand (m) zum Zyklusbeginn sein. Angenommen, wir kennen die Länge der Liste, können wir auch die Länge des Zyklus des Subtrahierens von m von der Listenlänge berechnen.