-
Notifications
You must be signed in to change notification settings - Fork 3
/
linked_list.rb
131 lines (103 loc) Β· 2.15 KB
/
linked_list.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
require_relative "node"
class LinkedList
attr_accessor :head, :tail
def get(n)
node = head
begin
raise IndexError if node.nil?
(n - 1).times { |_i| node = node.next }
rescue IndexError
puts "No node at index #{n}"
end
node
end
def append(node)
if @head.nil?
@head = node
else
@tail.next = node
end
@tail = node
end
def delete(node, prev_node)
if node.nil?
nil
elsif node == head && prev_node.nil?
self.head = node.next
elsif node == tail
self.tail = prev_node
prev_node.next = nil
elsif !prev_node.nil?
prev_node.next = node.next
end
end
def create_cycle_at(target_node)
tail.next = target_node
end
def cycle?
fast = head
slow = head
until fast.nil?
fast = fast.next
return true if fast == slow
unless fast.nil?
fast = fast.next
return true if fast == slow
end
slow = slow.next
end
false
end
def cycle_length
fast = head
slow = head
until fast.nil?
fast = fast.next
break if fast == slow
unless fast.nil?
fast = fast.next
break if fast == slow
end
slow = slow.next
end
return -1 if fast.nil?
fast = fast.next
nodes_passed = 1
until fast == slow
fast = fast.next
nodes_passed += 1
end
nodes_passed
end
def median
fast = head
slow = head
until fast.nil?
fast = fast.next
fast = fast.next unless fast.nil?
break if fast.nil?
slow = slow.next unless slow.next.nil?
end
slow
end
def cycle_head
# Initialize two pointers
fast = head
slow = head
# Move the fast pointer the cycle length
# By the time the fast pointer reaches the "tail",
# the slow pointer should be at the same spot as the fast
# pointer - which is at the head of the cycle
cycle_length.times { fast = fast.next }
until fast == slow
fast = fast.next
slow = slow.next
end
slow
end
def self.generate(*values)
list = new
values.each { |v| list.append Node.new(v) }
list
end
end