Rozumiem, że w celu wykrycia cyklu na liście połączonej mogę użyć podejścia Hare i Tortoise, które zawiera 2 wskaźniki (wolne i szybkie). Jednak po przeczytaniu w wiki i innych zasobach, nie rozumiem, dlaczego jest zagwarantowane, że te dwa wskaźniki spotkają się w złożoności czasu O (n).Wykrywanie cykli na liście połączonej z metodą Hare i Tortoise
Odpowiedz
Oto próba nieformalnego dowodu.
Kształt cyklu nie ma znaczenia. Może mieć długi ogon i pętlę pod koniec, lub tylko pętlę od początku do końca bez ogona. Niezależnie od kształtu cyklu jedno jest jasne - że wskaźnik żółwia nie może dogonić wskaźnika zająca. Jeśli obaj mieli się kiedykolwiek spotkać, wskaźnik zająca musi odciąć wskaźnik żółwia od tyłu.
Mając to ustalone, należy rozważyć dwa realnych możliwościach:
- zając wskaźnik jest o jeden krok za wskaźnik żółwia.
- Wskaźnik zająca znajduje się dwa kroki za wskaźnikiem żółwia.
Wszystkie większe odległości zostaną ostatecznie zredukowane do jednego lub dwóch.
Zakładając, że wskaźnik żółwia zawsze porusza się pierwszy (może być na odwrót), to w pierwszym przypadku wskaźnik żółwia robi krok do przodu. Teraz odległość między nimi wynosi 2. Kiedy wskaźnik zajścia ma teraz 2 kroki, trafią one do tego samego węzła. Oto ta sama ilustracja, dla łatwiejszego zrozumienia. Zbyt dużo tekstu może przeszkadzać.
♛ = hare ♙ = tortoise X = both meet ..♛♙... #1 - Initially, the hare is one step behind the tortoise. ..♛.♙.. #2 - Now the tortoise takes one step. now hare is two steps behind. ....X.. #3 - Next, the hare takes two steps and they meet!
Rozważmy teraz drugi przypadek, w którym odległość między nimi wynosi 2. powolny wskaźnik przesuwa się o jeden krok do przodu, a odległość między nimi staje 3. Następnie szybko wskaźnik porusza się do przodu i dwa kroki, odległość między nimi zmniejsza się do 1, który jest identyczny z pierwszym przypadkiem, w którym już udowodniliśmy, że spotkają się w jeszcze jednym kroku. Ponownie, zilustrowane dla łatwiejszego zrozumienia.
.♛.♙... #1 - Initially, the hare is two steps behind the tortoise. .♛..♙.. #2 - Now the tortoise takes one step and they become three steps apart. ...♛♙.. #3 - Next, the hare takes two steps which is identical to previous case.
Teraz, dlaczego ten algorytm jest gwarancją w O (n), wykorzystać to, co mamy już ustalone, że zając będzie spotkać żółwia zanim idzie naprzód. Oznacza to, że gdy obie znajdują się w pętli, zanim żółw zakończy kolejną rundę, spotka się z zająca, ponieważ zając porusza się dwa razy szybciej. W najgorszym przypadku pętla będzie kołem o n węzłach. Podczas gdy żółw może ukończyć tylko jedną rundę w n krokach, zając może ukończyć dwie rundy w tym czasie. Nawet jeśli zająca tęsknił za żółwiem w pierwszej rundzie (co zrobi), to w drugiej rundzie zdecydowanie dogoni żółwia.
Rozumiem, dzięki! Po prostu chcę się upewnić, że kompletnie go otrzymam - gdy powolny wskaźnik wejdzie w pętlę (ta szybka jest już w niej widoczna), gwarantuje się, że za pierwszym razem, gdy szybki wskaźnik spróbuje ominąć powolny, będą one faktycznie spotykać się. – Meir
Tak, absolutnie, a ponieważ szybki wskaźnik przemierza pętlę dwa razy w ruchach 'n' (biorąc pod uwagę długość pętli to' n'), gwarantują one spełnienie w 'O (n)'. Aby udowodnić, dlaczego nie możemy mieć niższej granicy niż 'O (n)', rozważmy najgorszy przypadek, w którym cała lista pętli wygląda jak krąg. Oba zaczynają się w węźle 0. Gdy wskaźnik szybkiego zakończenia kończy jedną pętlę, wskaźnik powolny znajduje się już w połowie listy kroków '(n/2)'. W kolejnych krokach '(n/2)' post zakończy kolejną iterację, a wolna zakończy pierwszą iterację. – Anurag
Niesamowite, wielkie dzięki! – Meir
Niech iteratory A
i B
przechodzą przez listę odpowiednio przez nich i przez dwa. Bardziej istnieje pętla. Wtedy, gdy A
wejdzie w pętlę, B
będzie już gdzieś w środku. Jeśli długość pętli jest K
, następnie B
będzie biegać to w ]K/2[
ruchów, więc co najwyżej 2*]K/2[
iteracji będziemy mieli sytuację, gdy B
pojawia się za A
w odległości 1: B->A
lub 2: B->.->A
, a to B
„th kolei. Potem oczywiście spotkamy się w ruchach 1
lub . Jeśli więc pętla istnieje i zaczyna się w jakiejś pozycji P
, wykonujemy co najwyżej 2*P + 2*]K/2[ + 2 = O(N)
iteracje.
//if you just want to check if there is a loop
loop = false;
item = head-of-list;
while (item != nil)
{
if (item.next < 0)
{
loop = true;
break;
}
else
{
actual = item;
item = item.next;
actual.next = actual.next * -1;
}
}
return loop;
- 1. Wykrywanie cykli w macierzy sąsiedztwa
- 2. Przełączanie dwóch elementów na liście połączonej
- 3. Zamiana węzłów na jednej, połączonej liście
- 4. Sortowanie według wpisu na połączonej liście w C?
- 5. Struktura lub klasa, która jest lepsza na liście połączonej?
- 6. Wykrywanie cykli wykresu (być może skierowanego lub nieukierunkowanego) w Haskell
- 7. licznik cykli z GCC
- 8. Subclipse i Tortoise SVN razem
- 9. Jak korzystać z dwóch różnych iteratorów na liście połączonej w języku Java?
- 10. Jak wyłączyć Tortoise BZR?
- 11. bloki, self, zatrzymywanie cykli
- 12. Z jakich narzędzi rozwoju i tworzenia cykli życia korzystasz?
- 13. jNetPcap na Androida: problem z metodą findAllDevs!
- 14. Jak wstawić element na posortowanej liście połączonej w ramach złożoności o stałym czasie?
- 15. Używanie `+ =` z metodą `wyślij`
- 16. Html.BeginForm() z metodą GET
- 17. Wykrywanie folderów HTML5 metodą przeciągania i upuszczania w Firefoksie. Czy to możliwe?
- 18. Filtrowanie połączonej kolumny
- 19. pętla na liście z usunięciem
- 20. Na czym polega problem z kluczem obcym kaskadowania wielu ścieżek i cykli?
- 21. Lista do posortowania metodą przeciągnij i upuść w Meteorzie
- 22. Wykrywanie narożników i krawędzi na wykresie
- 23. skopiuj połączoną listę z następnym i losowym wskaźnikiem, tylko uprawnienia odczytu są podane na liście
- 24. Uzyskiwanie tylko ostatnią wartość na połączonej tabeli z wymownym
- 25. Wykrywanie przeciągnij i upuść + wykrywanie nie działa
- 26. Krotki i słowniki znajdujące się na liście
- 27. MVC5 wisi na MapSignalR po ponownym podłączeniu po AppPool cykli
- 28. Wyliczanie cykli na wykresie przy użyciu algorytmu Tarjan za
- 29. Wykrywanie i porównywanie twarzy
- 30. wykrywanie twarzy i przycinanie
Szukasz formalnego dowodu matematycznego, czy tylko nieformalnego wyjaśnienia? –
Każda z nich jest w porządku. – Meir
Formalny (ale łatwy do zrozumienia) dowód. Sprawdź drugą odpowiedź od góry. http://stackoverflow.com/questions/2936213/explain-how-finding-cycle-start-node-in-cycle-linked-list-work – Hazem