Uczymy się pisać algorytm, który sprawdza, czy lista wiązana ma cykl, to jest czy się zapętla. Do dzieła.
Na początku klasa Node:
class Node{
constructor(val){
this.val = val;
this.next = null;
}
}
Teraz tworzymy 3 nodes, zapętlone:
let a = new Node("a");
let b = new Node("b");
let c = new Node("c");
a.next = b;
b.next = c;
c.next = a;
Teraz nasz algorytm:
function hasCycle(node){
let slow = node;
let fast = node;
while(fast !== null && fast.next !== null){
slow = slow.next;
fast = fast.next.next;
if(slow === fast)
return true;
}
return false;
}
console.log(hasCycle(a));
//true
Algorytm działa w ten sposób, że mamy szybki i wolny wskaźnik. Szybki skacze o 2 do przodu, wolny o 1 do przodu. Jeżeli lista się zapętla, to prędzej czy później szybki i wolny będą wskazywać to samo miejsce:
f,s
a ---> b --- c-|
^--------------|
s f
a ---> b --- c-|
^--------------|
f s
a ---> b --- c-|
^--------------|
f,s
a ---> b --- c-|
^--------------|
Ok, teraz zobaczmy jak działa bez zapętlenia:
a.next = b;
b.next = c;
c.next = null;
console.log(hasCycle(a));
//false
Mechanizm jest taki:
f,s
a -------> b ---------> c -----------> null
s f (f.next null, koniec pętli, false, cyklu nie ma)
a -------> b ---------> c -----------> null