forked from codeunion/data-structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
doubly_linked_list.rb
110 lines (86 loc) · 1.92 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
class DoublyLinkedList
class UnderflowError < StandardError; end
include Enumerable
attr_reader :head, :tail, :length
def initialize
@head = DoublyLinkedListNode.new(nil)
@tail = DoublyLinkedListNode.new(nil)
@length = 0
end
# O(1) time
def unshift(value)
@head = @head.insert_before(value)
@length += 1
if @length == 1
@head.next = @tail # Single node should be both head and tail
@tail = @head
end
self
end
# O(1) time
def shift
fail UnderflowError, "List is empty" if empty?
result = @head.value
if @length == 1
@head = @head.previous
@tail = @tail.next
else
@head.next.previous = @head.previous
@head = DoublyLinkedListNode(@head.next)
end
@length -= 1
result
end
# O(1) time
def empty?
self.head.empty?
end
def each(&block)
node = self.head
until node.empty?
block.call(node.value)
node = node.next
end
self
end
end
def DoublyLinkedListNode(value)
case value
when DoublyLinkedListNode
value
else
DoublyLinkedListNode.new(value)
end
end
class DoublyLinkedListNode
include Enumerable
attr_accessor :previous, :value, :next
def initialize(value = nil, previous_node = nil, next_node = nil)
@previous = previous_node
@value = value
@next = next_node
end
# O(1) time
# Insert +value+ after this DoublyLinkedListNode and return new DoublyLinkedListNode
def insert_after(value)
node = DoublyLinkedListNode(value)
# Need to implement this
node
end
# O(1) time
# Insert +value+ before this DoublyLinkedListNode and return new DoublyLinkedListNode
def insert_before(value)
node = DoublyLinkedListNode(value)
if self.empty?
node.previous = self
else
node.previous = self.previous
node.next = self
self.previous = node
end
node
end
def empty?
value.nil?
end
end