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