Алгоритм виявлення циклу Флойда | Визначення початкової точки циклу


32

Я шукаю допомоги з розумінням алгоритму виявлення циклу Флойда. Я пояснив пояснення у wikipedia ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Я бачу, як алгоритм виявляє цикл за O (n) час. Однак я не в змозі уявити той факт, що як тільки вказівники черепахи та зайця зустрічаються вперше, початок циклу можна визначити, перемістивши вказівник черепахи назад на початок, а потім перемістивши черепаху та зайця покроково. Місце, де вони вперше зустрічаються, - це початок циклу.

Чи може хтось допомогти, надавши пояснення, сподіваюся, відмінні від пояснень у Вікіпедії, оскільки я не в змозі зрозуміти / візуалізувати його?


3
Я знайшов відповідь на stackoverflow. Дякую, якщо хтось розглядав це за мене. А для тих, хто подобається мені, хотіли пояснення, будь ласка, зверніться до: stackoverflow.com/questions/3952805/… Обрана відповідь на запитання, пояснює це!
Анураг Капур

Привіт @Anurag. Просто для інформації, я зробив запис у блозі на «Черепаха і заєць» Алгоритм тут
Kyle

Чи знаєте ви, чому fastзмінна, або "заєць", повинен рухатись удвічі швидше, ніж черепаха, а не лише вперед?
devdropper87

Чудово пояснено з програмою: javabypatel.blogspot.in/2015/12/detect-loop-in-linked-list.html
Jayesh

Відповіді:


47

Ви можете посилатися на "Виявлення початку циклу в спільно пов'язаному списку" , ось уривок:

введіть тут опис зображення

Пройдена відстань slowPointerдо зустрічі =x+y

fastPointer =(x+y+z)+y

Оскільки fastPointerподорожує з подвійною швидкістю slowPointer, і час є постійним для обох, коли досягається точка зустрічі. Отже, використовуючи просте відношення швидкості, часу та відстані ( slowPointerпроїхав половину відстані):

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

Отже, пересуваючись slowPointerдо початку пов’язаного списку, складаючи обидва slowPointerта fastPointerпереміщуючи по одному вузлу, обидва мають однакову відстань для покриття .

Вони дістануться в точці, коли цикл починається у пов'язаному списку.


2
Тут ви зробили припущення, що вони зустрінуться після одного обертання. Можуть бути випадки (коли цикл малий), коли вони можуть зустрітися після певного «ні». обертів.
Navjot Waraich

1
@JotWaraich зображення не є репрезентативним для всіх випадків; логіка, проте, досі дотримується
denis631

3
це найбільш пряма відповідь про цей алгоритм у всьому Інтернеті
Маршалл X

7

Я сприйняв прийняту відповідь як доказ і в інших місцях. Однак, хоча його легко вихопити, це неправильно. Що це доводить

x=z

Що ви насправді хочете довести, це (використовуючи ті самі змінні, що описані на схемі у прийнятій відповіді вище):

z=x mod (y+z)

(y+z)L

Отже, що ми хочемо довести, це:

z=x mod L

Або що z відповідає контенту x (модуль L)

Наступний доказ має більше сенсу для мене:

M=x+y

2(x+y)=M+kLkx+yL

x+y=kL

x=kLy

xLyMx+y


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.