Существует простой подход с использованием двух указателей: первый указатель увеличивается на единицу, а второй - вдвое быстрее, чем медленный указатель.
Итак, связанный список в вашем случае на самом деле A->B->C->D->E->F->C
, что означает, что F снова указывает на C. Итак, подход похож на ниже
1. Продолжайте увеличивать два pointers
до тех пор, пока они не совпадут. Таким образом, в приведенном выше случае у нас будет этот набор шагов
Медленный указатель: A B C D E
Быстрый указатель: A C E C E
Итак, мы останавливаемся на E, что указывает на наличие цикла. Теперь нам нужно найти узел цикла.
Теперь от E переместите медленный указатель в начало связанного списка и создайте новый указатель, который указывает на E и также увеличивается на 1. Точка, в которой встречаются эти два указателя, на самом деле является узлом цикла.
Указатель с начала: A B C Новый указатель: E F C
Итак, как вы видите, они встречаются в точке C, и мы закончили поиск узла цикла в связанном списке.
Обновление. Чтобы получить математическое подтверждение этого подхода, обратитесь к этому замечательному вопросу и посмотрите ответ @Jim Lewis вместе со всеми комментариями под ответом. Объясните, как найти узел начала цикла в связанном списке цикла работать?
person
Algorithmist
schedule
25.08.2013