1+ // import visualization libraries {
2+ const { Array2DTracer, Layout, LogTracer, GraphTracer, Tracer, VerticalLayout } = require ( 'algorithm-visualizer' ) ;
3+ // }
4+
5+
6+ // define tracer variables {
7+ function ListNode ( val ) {
8+ this . val = val
9+ this . next = null
10+ }
11+
12+ const node0 = new ListNode ( 0 )
13+ const node1 = new ListNode ( 1 )
14+ const node2 = new ListNode ( 2 )
15+ const node3 = new ListNode ( 3 )
16+ const node4 = new ListNode ( 4 )
17+ const node5 = new ListNode ( 5 )
18+ const node6 = new ListNode ( 6 )
19+
20+ const list = node0
21+ list . next = node1
22+ list . next . next = node2
23+ list . next . next . next = node3
24+ list . next . next . next . next = node4
25+ list . next . next . next . next . next = node5
26+ list . next . next . next . next . next . next = node6
27+ list . next . next . next . next . next . next . next = node2
28+
29+ const graphTracer = new GraphTracer ( "Linked List" ) . directed ( )
30+ const logTracer = new LogTracer ( "Console" )
31+ Layout . setRoot ( new VerticalLayout ( [ graphTracer , logTracer ] ) )
32+
33+ graphTracer . addNode ( node0 . val )
34+ graphTracer . addNode ( node1 . val )
35+ graphTracer . addNode ( node2 . val )
36+ graphTracer . addNode ( node3 . val )
37+ graphTracer . addNode ( node4 . val )
38+ graphTracer . addNode ( node5 . val )
39+ graphTracer . addNode ( node6 . val )
40+ graphTracer . addEdge ( node0 . val , node1 . val )
41+ graphTracer . addEdge ( node1 . val , node2 . val )
42+ graphTracer . addEdge ( node2 . val , node3 . val )
43+ graphTracer . addEdge ( node3 . val , node4 . val )
44+ graphTracer . addEdge ( node4 . val , node5 . val )
45+ graphTracer . addEdge ( node5 . val , node6 . val )
46+ graphTracer . addEdge ( node6 . val , node2 . val )
47+ Tracer . delay ( )
48+ // }
49+
50+ var listHasCycle = function ( head ) {
51+ // visualize {
52+ graphTracer . select ( head . val )
53+ graphTracer . visit ( head . val )
54+ Tracer . delay ( )
55+ graphTracer . deselect ( head . val )
56+ graphTracer . leave ( head . val )
57+ // }
58+
59+ // 1. is there a cycle?
60+ let slow = head . next
61+ let fast = head . next . next
62+ // visualize {
63+ graphTracer . select ( slow . val )
64+ graphTracer . visit ( fast . val )
65+ Tracer . delay ( )
66+ graphTracer . deselect ( slow . val )
67+ graphTracer . leave ( fast . val )
68+ // }
69+ while ( slow !== fast ) {
70+ slow = slow . next
71+ fast = fast . next . next
72+ // visualize {
73+ graphTracer . select ( slow . val )
74+ graphTracer . visit ( fast . val )
75+ Tracer . delay ( )
76+ graphTracer . deselect ( slow . val )
77+ graphTracer . leave ( fast . val )
78+ // }
79+ }
80+
81+ // 2. where does the cycle start?
82+ let cycleStartPosition = 0
83+ slow = head
84+ // visualize {
85+ graphTracer . select ( slow . val )
86+ graphTracer . visit ( fast . val )
87+ Tracer . delay ( )
88+ graphTracer . deselect ( slow . val )
89+ graphTracer . leave ( fast . val )
90+ // }
91+ while ( slow !== fast ) {
92+ slow = slow . next
93+ fast = fast . next
94+ cycleStartPosition += 1
95+ // visualize {
96+ graphTracer . select ( slow . val )
97+ graphTracer . visit ( fast . val )
98+ Tracer . delay ( )
99+ graphTracer . deselect ( slow . val )
100+ graphTracer . leave ( fast . val )
101+ // }
102+ }
103+
104+ // 3. what is the length of the cycle?
105+ let cycleLength = 1
106+ fast = slow . next
107+ // visualize {
108+ graphTracer . select ( slow . val )
109+ graphTracer . visit ( fast . val )
110+ Tracer . delay ( )
111+ graphTracer . deselect ( slow . val )
112+ graphTracer . leave ( fast . val )
113+ // }
114+ while ( slow !== fast ) {
115+ fast = fast . next
116+ cycleLength += 1
117+ // visualize {
118+ graphTracer . select ( slow . val )
119+ graphTracer . visit ( fast . val )
120+ Tracer . delay ( )
121+ graphTracer . deselect ( slow . val )
122+ graphTracer . leave ( fast . val )
123+ // }
124+ }
125+
126+ return {
127+ cycleLength,
128+ cycleStartPosition,
129+ }
130+ }
131+ // log {
132+ const res = listHasCycle ( list )
133+ logTracer . print ( `cycle start position: ${ res . cycleStartPosition } ` )
134+ logTracer . print ( "\n" )
135+ logTracer . print ( `cycle length: ${ res . cycleLength } ` )
136+ // }
0 commit comments