forked from isisAnchalee/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoubly-linked-list.rb
89 lines (69 loc) · 1.47 KB
/
doubly-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
class Link
attr_accessor :key, :val, :next, :prev
def initialize(key = nil, val = nil, nxt = nil, prev = nil)
@key, @val, @next, @prev = key, val, nxt, prev
end
def to_s
"#{@key}, #{@val}"
end
end
class LinkedList
attr_reader :head, :tail
include Enumerable
def initialize
@head = Link.new
@tail = Link.new
@head.next = @tail
@tail.prev = @head
end
def [](i)
each_with_index { |link, j| return link if i == j }
nil
end
def first
empty? ? nil : @head.next
end
def last
empty? ? nil : @tail.prev
end
def empty?
@head.next == @tail
end
def get(key)
each { |link| return link.val if link.key == key }
nil
end
def include?(key)
any? { |link| link.key == key }
end
def insert(key, val)
each { |link| return link.val = val if link.key == key }
new_link = Link.new(key, val)
@tail.prev.next = new_link
new_link.prev = @tail.prev
new_link.next = @tail
@tail.prev = new_link
new_link
end
def remove(key)
each do |link|
if link.key == key
link.prev.next = link.next
link.next.prev = link.prev
link.next, link.prev = nil, nil
return link.val
end
end
nil
end
def each
current_link = @head.next
until current_link == @tail
yield current_link
current_link = current_link.next
end
end
def to_s
inject([]) { |acc, link| acc << "[#{link.key}, #{link.val}]" }.join(", ")
end
end