-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeneric_list.rb
93 lines (82 loc) · 1.76 KB
/
generic_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
##
# Should not be instantiated directly.
# See subclasses, like OrderedList and SortedList
class GenericList
class Node
def initialize value, nxt=nil, prv=nil
@value = value
@nxt = nxt
@prv = prv
end
attr_accessor :value
attr_reader :nxt, :prv
##
# Create a new node and insert it after this one.
def insert_after value
node = Node.new value, @nxt, self
@nxt.prv = node if @nxt
@nxt = node
end
alias :insert :insert_after
##
# Create a new node and insert if before this one.
def insert_before value
node = Node.new value, self, @prv
@prv.nxt = node if @prv
@prv = node
end
##
# Remove this node.
# Returns a pointer to the nxt node.
def remove
@nxt.prv = @prv if @nxt
@prv.nxt = @nxt if @prv
end
end
include Enumerable
def initialize
@head = nil
@length = 0
end
attr_reader :length
##
# Remove value from list.
#
# @param value value to delete
# @param n max number to remove (<1 means "all")
# @return value or nil
def delete value, n=0
return if @head.nil?
x = n # remember value (see end of function)
while @head && @head.value == value
@length -= 1
@head = @head.remove
n -= 1
return value if n == 0
any = true
end
ptr = @head
while ptr
if ptr.value == value
@length -= 1
ptr = ptr.remove
n -= 1
return value if n == 0
else
ptr = ptr.nxt
end
end
value if x != n
end
##
# Invoke block once for each value in the list.
def each &block
return enum_for(:each) unless block_given?
ptr = @head
while ptr
yield ptr.value
ptr = ptr.nxt
end
nil
end
end