Рубрики
Без рубрики

[Алгоритм Флойда] Как обнаружить цикл в связанном списке в Python?

В этом руководстве вы узнаете, как реализовать простую программу Python для обнаружения, если связанный список состоит из цикла или нет. Если вам нужен краткий переподготовка к подключенным спискам, проверить этот блог. https://youtu.be/x6dfcncz8tk Определение цикла в связанном списке Связанный список может состоять из … [алгоритм Floyd] Как обнаружить цикл в связанном списке в Python? Прочитайте больше “

Автор оригинала: Neeraj Sujan.

В этом руководстве вы узнаете, как реализовать простую программу Python для обнаружения, если связанный список состоит из цикла или нет. Если вам нужен краткий переподготовка к подключенным спискам, проверить этот блог.

Определение цикла в связанном списке

Связанный список может состоять из цикла, если хвостовой узел связанного списка указывает на другой узел в списке. Давайте увидим небольшой пример, чтобы понять концепцию цикла в связанном списке.

В приведенной выше показателе вы можете видеть, что узел хвостового узла связанного списка, а не указывает на NULL, указывает на другой узел – второй узел в списке. Если такой сценарий возникает, мы говорим, что есть цикл или цикл в списке.

Инициализация и настройка

Сначала мы начнем с помощью инициализации узлов и построении связанного списка.

from linked_list import Node, LinkedList
 
node1 =  Node(5)
node2 =  Node(6)
node3 =  Node(7)
node4 =  Node(8)
node5 =  Node(9)
 
 
ll = LinkedList()
 
ll.insert_back(node1)
ll.insert_back(node2)
ll.insert_back(node3)
ll.insert_back(node4)
ll.insert_back(node5)

Теперь мы подключам пятый узел к 3-м узлу, образующему цикл.

node5.next = node3

Подход 1: наивный подход

Теперь мы посмотрим на простой подход к реализации логики, чтобы узнать, состоит ли список цикла или нет. Один из подходов будет хранить адрес узла в словаре, когда мы проходим через список, и, как только мы столкнулись с узлом, адрес которого уже был в словаре, можно сказать, что в списке был цикл. Давайте посмотрим, как мы можем реализовать это в Python

 
addresses = {}
temp_node = node1
while (temp_node):
   address = id(temp_node)
   print(address)
   if address not in addresses:
       addresses[address] = 1
   else:
       print('cycle in a linked list')
       print(temp_node.data)
       break
   temp_node = temp_node.next

Недостатком предыдущего подхода заключается в том, что он занимает 0 (N) сложность пространства. Можем ли мы решить эту проблему в O (1) космической сложности?

Подход 2: алгоритм обнаружения цикла Floyd

Мы можем решить эту проблему путем инициализации двух указателей, медленного указателя и быстрой указателя. На каждой итерации мы увеличиваем медленный указатель на 1 и быстрый указатель на 2. Затем мы проверяем, будет ли медленный указатель равен быстрой указателю I.e. Сделайте оба указывающие на тот же узел. Если это так, мы можем сказать, что в связанном списке есть цикл или цикл. Как только мы найдем цикл, мы можем вырваться из цикла While.

Демонстрация

Представьте, что у нас есть список с 5 узлами, как показано на рисунке ниже. Как вы можете видеть хвостовой узел I.E. Узел со значением 9 указывает на узел со значением 7 или 3-м узлом в списке, тем самым формируя цикл или цикл.

Итерация 1:

В первой итерации медленный указатель увеличивается на 1 и быстрый указатель на 2. Как вы можете видеть на рисунке ниже, медленный указатель теперь указывает на узел со значением 6, и быстрый указатель указывает на узел со значением 7.

Итерация 2:

Во второй итерации медленный указатель указывает на узел со значением 7 и быстрыми указывающими указывающими на узел со значением 9 или последним узлом.

Итерация 3:

В третьей итерации мы наблюдаем, что как медленные, так и быстрые указатели указывают на тот же узел I.e. Узел со значением 8. В этом случае мы можем сделать вывод, что в списке есть цикл.

Дайте нам знать, как мы можем реализовать логику Adobe в Python.

Сначала мы инициализируем медленный указатель и быстрый указатель, указывающий на головной узел или первый узел. Затем мы запустим Wide Plup, и мы запускаем петлю, пока медленный указатель действителен, быстрый указатель действителен, и следующее значение быстрого указателя является действительным. Затем мы продолжаем увеличивать медленные и быстрые указатели на 1 и 2 соответственно, и если оба указателя имеют одинаковое значение адреса, мы вырвались из цикла и распечатаем, что был цикл в связанном списке. Вы можете найти всю логику ниже.

slow_ptr = node1
fast_ptr = node1
 
while (slow_ptr and fast_ptr and fast_ptr.next):
   slow_ptr = slow_ptr.next
   fast_ptr = fast_ptr.next.next
   if slow_ptr == fast_ptr:
       print('loop in a linked list', slow_ptr.data)
       break
   else:
       print(slow_ptr.data, fast_ptr.data)

Этот алгоритм также называется Алгоритм обнаружения цикла Флойда Отказ

Вывод

В этом руководстве мы видели, как мы можем обнаружить цикл в цикле с использованием алгоритма обнаружения цикла Floyd. Этот алгоритм может обнаружить петлю в O (1) Космическая сложность и O (n) Сложность времени.