stakach-algorithms 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +97 -97
- data/Rakefile +27 -27
- data/ext/algorithms/string/extconf.rb +4 -4
- data/ext/algorithms/string/string.c +70 -70
- data/ext/containers/bst/bst.c +249 -249
- data/ext/containers/bst/extconf.rb +4 -4
- data/ext/containers/deque/deque.c +248 -248
- data/ext/containers/deque/extconf.rb +4 -4
- data/ext/containers/rbtree_map/extconf.rb +4 -4
- data/ext/containers/rbtree_map/rbtree.c +500 -500
- data/ext/containers/splaytree_map/extconf.rb +4 -4
- data/ext/containers/splaytree_map/splaytree.c +421 -421
- data/lib/algorithms/search.rb +85 -85
- data/lib/algorithms/sort.rb +242 -242
- data/lib/algorithms/string.rb +10 -10
- data/lib/algorithms/version.rb +1 -1
- data/lib/algorithms.rb +69 -69
- data/lib/containers/deque.rb +176 -176
- data/lib/containers/heap.rb +506 -506
- data/lib/containers/kd_tree.rb +112 -112
- data/lib/containers/priority_queue.rb +116 -116
- data/lib/containers/queue.rb +71 -71
- data/lib/containers/rb_tree_map.rb +402 -402
- data/lib/containers/splay_tree_map.rb +273 -273
- data/lib/containers/stack.rb +70 -70
- data/lib/containers/suffix_array.rb +71 -71
- data/lib/containers/trie.rb +187 -187
- metadata +3 -3
@@ -1,273 +1,273 @@
|
|
1
|
-
require 'containers/stack'
|
2
|
-
=begin rdoc
|
3
|
-
A SplayTreeMap is a map that is stored in ascending order of its keys, determined by applying
|
4
|
-
the function <=> to compare keys. No duplicate values for keys are allowed, so new values of a key
|
5
|
-
overwrites the old value of the key.
|
6
|
-
|
7
|
-
A major advantage of SplayTreeMap over a Hash is the fact that keys are stored in order and can thus be
|
8
|
-
iterated over in order. Also, Splay Trees are self-optimizing as recently accessed nodes stay near
|
9
|
-
the root and are easily re-accessed later. Splay Trees are also more simply implemented than Red-Black
|
10
|
-
trees.
|
11
|
-
|
12
|
-
Splay trees have amortized O(log n) performance for most methods, but are O(n) worst case. This happens
|
13
|
-
when keys are added in sorted order, causing the tree to have a height of the number of items added.
|
14
|
-
|
15
|
-
=end
|
16
|
-
module Algorithms
|
17
|
-
module Containers
|
18
|
-
class RubySplayTreeMap
|
19
|
-
include Enumerable
|
20
|
-
|
21
|
-
Node = Struct.new(:key, :value, :left, :right)
|
22
|
-
|
23
|
-
# Create and initialize a new empty SplayTreeMap.
|
24
|
-
def initialize
|
25
|
-
@size = 0
|
26
|
-
clear
|
27
|
-
end
|
28
|
-
|
29
|
-
# Insert an item with an associated key into the SplayTreeMap, and returns the item inserted
|
30
|
-
#
|
31
|
-
# Complexity: amortized O(log n)
|
32
|
-
#
|
33
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
34
|
-
# map.push("MA", "Massachusetts") #=> "Massachusetts"
|
35
|
-
# map.get("MA") #=> "Massachusetts"
|
36
|
-
def push(key, value)
|
37
|
-
if @root.nil?
|
38
|
-
@root = Node.new(key, value, nil, nil)
|
39
|
-
@size = 1
|
40
|
-
return value
|
41
|
-
end
|
42
|
-
splay(key)
|
43
|
-
|
44
|
-
cmp = (key <=> @root.key)
|
45
|
-
if cmp == 0
|
46
|
-
@root.value = value
|
47
|
-
return value
|
48
|
-
end
|
49
|
-
node = Node.new(key, value, nil, nil)
|
50
|
-
if cmp < 1
|
51
|
-
node.left = @root.left
|
52
|
-
node.right = @root
|
53
|
-
@root.left = nil
|
54
|
-
else
|
55
|
-
node.right = @root.right
|
56
|
-
node.left = @root
|
57
|
-
@root.right = nil
|
58
|
-
end
|
59
|
-
@root = node
|
60
|
-
@size += 1
|
61
|
-
value
|
62
|
-
end
|
63
|
-
alias_method :[]=, :push
|
64
|
-
|
65
|
-
# Return the number of items in the SplayTreeMap.
|
66
|
-
#
|
67
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
68
|
-
# map.push("MA", "Massachusetts")
|
69
|
-
# map.push("GA", "Georgia")
|
70
|
-
# map.size #=> 2
|
71
|
-
def size
|
72
|
-
@size
|
73
|
-
end
|
74
|
-
|
75
|
-
# Remove all elements from the SplayTreeMap
|
76
|
-
#
|
77
|
-
# Complexity: O(1)
|
78
|
-
#
|
79
|
-
def clear
|
80
|
-
@root = nil
|
81
|
-
@size = 0
|
82
|
-
@header = Node.new(nil, nil, nil, nil)
|
83
|
-
end
|
84
|
-
|
85
|
-
# Return the height of the tree structure in the SplayTreeMap.
|
86
|
-
#
|
87
|
-
# Complexity: O(log n)
|
88
|
-
#
|
89
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
90
|
-
# map.push("MA", "Massachusetts")
|
91
|
-
# map.push("GA", "Georgia")
|
92
|
-
# map.height #=> 2
|
93
|
-
def height
|
94
|
-
height_recursive(@root)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Return true if key is found in the SplayTreeMap, false otherwise.
|
98
|
-
#
|
99
|
-
# Complexity: amortized O(log n)
|
100
|
-
#
|
101
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
102
|
-
# map["MA"] = "Massachusetts"
|
103
|
-
# map["GA"] = "Georgia"
|
104
|
-
# map.has_key?("GA") #=> true
|
105
|
-
# map.has_key?("DE") #=> false
|
106
|
-
def has_key?(key)
|
107
|
-
!get(key).nil?
|
108
|
-
end
|
109
|
-
|
110
|
-
# Return the item associated with the key, or nil if none found.
|
111
|
-
#
|
112
|
-
# Complexity: amortized O(log n)
|
113
|
-
#
|
114
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
115
|
-
# map.push("MA", "Massachusetts")
|
116
|
-
# map.push("GA", "Georgia")
|
117
|
-
# map.get("GA") #=> "Georgia"
|
118
|
-
def get(key)
|
119
|
-
return nil if @root.nil?
|
120
|
-
|
121
|
-
splay(key)
|
122
|
-
(@root.key <=> key) == 0 ? @root.value : nil
|
123
|
-
end
|
124
|
-
alias_method :[], :get
|
125
|
-
|
126
|
-
# Return the smallest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
|
127
|
-
#
|
128
|
-
# Complexity: amortized O(log n)
|
129
|
-
#
|
130
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
131
|
-
# map["MA"] = "Massachusetts"
|
132
|
-
# map["GA"] = "Georgia"
|
133
|
-
# map.min #=> ["GA", "Georgia"]
|
134
|
-
def min
|
135
|
-
return nil if @root.nil?
|
136
|
-
n = @root
|
137
|
-
while n.left
|
138
|
-
n = n.left
|
139
|
-
end
|
140
|
-
splay(n.key)
|
141
|
-
return [n.key, n.value]
|
142
|
-
end
|
143
|
-
|
144
|
-
# Return the largest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
|
145
|
-
#
|
146
|
-
# Complexity: amortized O(log n)
|
147
|
-
#
|
148
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
149
|
-
# map["MA"] = "Massachusetts"
|
150
|
-
# map["GA"] = "Georgia"
|
151
|
-
# map.max #=> ["MA", "Massachusetts"]
|
152
|
-
def max
|
153
|
-
return nil if @root.nil?
|
154
|
-
n = @root
|
155
|
-
while n.right
|
156
|
-
n = n.right
|
157
|
-
end
|
158
|
-
splay(n.key)
|
159
|
-
return [n.key, n.value]
|
160
|
-
end
|
161
|
-
|
162
|
-
# Deletes the item and key if it's found, and returns the item. Returns nil
|
163
|
-
# if key is not present.
|
164
|
-
#
|
165
|
-
# Complexity: amortized O(log n)
|
166
|
-
#
|
167
|
-
# map = Algorithms::Containers::SplayTreeMap.new
|
168
|
-
# map["MA"] = "Massachusetts"
|
169
|
-
# map["GA"] = "Georgia"
|
170
|
-
# map.delete("GA") #=> "Georgia"
|
171
|
-
# map.delete("DE") #=> nil
|
172
|
-
def delete(key)
|
173
|
-
return nil if @root.nil?
|
174
|
-
deleted = nil
|
175
|
-
splay(key)
|
176
|
-
if (key <=> @root.key) == 0 # The key exists
|
177
|
-
deleted = @root.value
|
178
|
-
if @root.left.nil?
|
179
|
-
@root = @root.right
|
180
|
-
else
|
181
|
-
x = @root.right
|
182
|
-
@root = @root.left
|
183
|
-
splay(key)
|
184
|
-
@root.right = x
|
185
|
-
end
|
186
|
-
end
|
187
|
-
deleted
|
188
|
-
end
|
189
|
-
|
190
|
-
# Iterates over the SplayTreeMap in ascending order. Uses an iterative, not recursive, approach.
|
191
|
-
def each
|
192
|
-
return nil unless @root
|
193
|
-
stack = Stack.new
|
194
|
-
cursor = @root
|
195
|
-
loop do
|
196
|
-
if cursor
|
197
|
-
stack.push(cursor)
|
198
|
-
cursor = cursor.left
|
199
|
-
else
|
200
|
-
unless stack.empty?
|
201
|
-
cursor = stack.pop
|
202
|
-
yield(cursor.key, cursor.value)
|
203
|
-
cursor = cursor.right
|
204
|
-
else
|
205
|
-
break
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
# Moves a key to the root, updating the structure in each step.
|
212
|
-
def splay(key)
|
213
|
-
l, r = @header, @header
|
214
|
-
t = @root
|
215
|
-
@header.left, @header.right = nil, nil
|
216
|
-
|
217
|
-
loop do
|
218
|
-
if (key <=> t.key) == -1
|
219
|
-
break unless t.left
|
220
|
-
if (key <=> t.left.key) == -1
|
221
|
-
y = t.left
|
222
|
-
t.left = y.right
|
223
|
-
y.right = t
|
224
|
-
t = y
|
225
|
-
break unless t.left
|
226
|
-
end
|
227
|
-
r.left = t
|
228
|
-
r = t
|
229
|
-
t = t.left
|
230
|
-
elsif (key <=> t.key) == 1
|
231
|
-
break unless t.right
|
232
|
-
if (key <=> t.right.key) == 1
|
233
|
-
y = t.right
|
234
|
-
t.right = y.left
|
235
|
-
y.left = t
|
236
|
-
t = y
|
237
|
-
break unless t.right
|
238
|
-
end
|
239
|
-
l.right = t
|
240
|
-
l = t
|
241
|
-
t = t.right
|
242
|
-
else
|
243
|
-
break
|
244
|
-
end
|
245
|
-
end
|
246
|
-
l.right = t.left
|
247
|
-
r.left = t.right
|
248
|
-
t.left = @header.right
|
249
|
-
t.right = @header.left
|
250
|
-
@root = t
|
251
|
-
end
|
252
|
-
private :splay
|
253
|
-
|
254
|
-
# Recursively determine height
|
255
|
-
def height_recursive(node)
|
256
|
-
return 0 if node.nil?
|
257
|
-
|
258
|
-
left_height = 1 + height_recursive(node.left)
|
259
|
-
right_height = 1 + height_recursive(node.right)
|
260
|
-
|
261
|
-
left_height > right_height ? left_height : right_height
|
262
|
-
end
|
263
|
-
private :height_recursive
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
begin
|
268
|
-
require 'CSplayTreeMap'
|
269
|
-
Containers::SplayTreeMap = Containers::CSplayTreeMap
|
270
|
-
rescue
|
271
|
-
Containers::SplayTreeMap = Containers::RubySplayTreeMap
|
272
|
-
end
|
273
|
-
end
|
1
|
+
require 'containers/stack'
|
2
|
+
=begin rdoc
|
3
|
+
A SplayTreeMap is a map that is stored in ascending order of its keys, determined by applying
|
4
|
+
the function <=> to compare keys. No duplicate values for keys are allowed, so new values of a key
|
5
|
+
overwrites the old value of the key.
|
6
|
+
|
7
|
+
A major advantage of SplayTreeMap over a Hash is the fact that keys are stored in order and can thus be
|
8
|
+
iterated over in order. Also, Splay Trees are self-optimizing as recently accessed nodes stay near
|
9
|
+
the root and are easily re-accessed later. Splay Trees are also more simply implemented than Red-Black
|
10
|
+
trees.
|
11
|
+
|
12
|
+
Splay trees have amortized O(log n) performance for most methods, but are O(n) worst case. This happens
|
13
|
+
when keys are added in sorted order, causing the tree to have a height of the number of items added.
|
14
|
+
|
15
|
+
=end
|
16
|
+
module Algorithms
|
17
|
+
module Containers
|
18
|
+
class RubySplayTreeMap
|
19
|
+
include Enumerable
|
20
|
+
|
21
|
+
Node = Struct.new(:key, :value, :left, :right)
|
22
|
+
|
23
|
+
# Create and initialize a new empty SplayTreeMap.
|
24
|
+
def initialize
|
25
|
+
@size = 0
|
26
|
+
clear
|
27
|
+
end
|
28
|
+
|
29
|
+
# Insert an item with an associated key into the SplayTreeMap, and returns the item inserted
|
30
|
+
#
|
31
|
+
# Complexity: amortized O(log n)
|
32
|
+
#
|
33
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
34
|
+
# map.push("MA", "Massachusetts") #=> "Massachusetts"
|
35
|
+
# map.get("MA") #=> "Massachusetts"
|
36
|
+
def push(key, value)
|
37
|
+
if @root.nil?
|
38
|
+
@root = Node.new(key, value, nil, nil)
|
39
|
+
@size = 1
|
40
|
+
return value
|
41
|
+
end
|
42
|
+
splay(key)
|
43
|
+
|
44
|
+
cmp = (key <=> @root.key)
|
45
|
+
if cmp == 0
|
46
|
+
@root.value = value
|
47
|
+
return value
|
48
|
+
end
|
49
|
+
node = Node.new(key, value, nil, nil)
|
50
|
+
if cmp < 1
|
51
|
+
node.left = @root.left
|
52
|
+
node.right = @root
|
53
|
+
@root.left = nil
|
54
|
+
else
|
55
|
+
node.right = @root.right
|
56
|
+
node.left = @root
|
57
|
+
@root.right = nil
|
58
|
+
end
|
59
|
+
@root = node
|
60
|
+
@size += 1
|
61
|
+
value
|
62
|
+
end
|
63
|
+
alias_method :[]=, :push
|
64
|
+
|
65
|
+
# Return the number of items in the SplayTreeMap.
|
66
|
+
#
|
67
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
68
|
+
# map.push("MA", "Massachusetts")
|
69
|
+
# map.push("GA", "Georgia")
|
70
|
+
# map.size #=> 2
|
71
|
+
def size
|
72
|
+
@size
|
73
|
+
end
|
74
|
+
|
75
|
+
# Remove all elements from the SplayTreeMap
|
76
|
+
#
|
77
|
+
# Complexity: O(1)
|
78
|
+
#
|
79
|
+
def clear
|
80
|
+
@root = nil
|
81
|
+
@size = 0
|
82
|
+
@header = Node.new(nil, nil, nil, nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Return the height of the tree structure in the SplayTreeMap.
|
86
|
+
#
|
87
|
+
# Complexity: O(log n)
|
88
|
+
#
|
89
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
90
|
+
# map.push("MA", "Massachusetts")
|
91
|
+
# map.push("GA", "Georgia")
|
92
|
+
# map.height #=> 2
|
93
|
+
def height
|
94
|
+
height_recursive(@root)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return true if key is found in the SplayTreeMap, false otherwise.
|
98
|
+
#
|
99
|
+
# Complexity: amortized O(log n)
|
100
|
+
#
|
101
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
102
|
+
# map["MA"] = "Massachusetts"
|
103
|
+
# map["GA"] = "Georgia"
|
104
|
+
# map.has_key?("GA") #=> true
|
105
|
+
# map.has_key?("DE") #=> false
|
106
|
+
def has_key?(key)
|
107
|
+
!get(key).nil?
|
108
|
+
end
|
109
|
+
|
110
|
+
# Return the item associated with the key, or nil if none found.
|
111
|
+
#
|
112
|
+
# Complexity: amortized O(log n)
|
113
|
+
#
|
114
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
115
|
+
# map.push("MA", "Massachusetts")
|
116
|
+
# map.push("GA", "Georgia")
|
117
|
+
# map.get("GA") #=> "Georgia"
|
118
|
+
def get(key)
|
119
|
+
return nil if @root.nil?
|
120
|
+
|
121
|
+
splay(key)
|
122
|
+
(@root.key <=> key) == 0 ? @root.value : nil
|
123
|
+
end
|
124
|
+
alias_method :[], :get
|
125
|
+
|
126
|
+
# Return the smallest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
|
127
|
+
#
|
128
|
+
# Complexity: amortized O(log n)
|
129
|
+
#
|
130
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
131
|
+
# map["MA"] = "Massachusetts"
|
132
|
+
# map["GA"] = "Georgia"
|
133
|
+
# map.min #=> ["GA", "Georgia"]
|
134
|
+
def min
|
135
|
+
return nil if @root.nil?
|
136
|
+
n = @root
|
137
|
+
while n.left
|
138
|
+
n = n.left
|
139
|
+
end
|
140
|
+
splay(n.key)
|
141
|
+
return [n.key, n.value]
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return the largest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
|
145
|
+
#
|
146
|
+
# Complexity: amortized O(log n)
|
147
|
+
#
|
148
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
149
|
+
# map["MA"] = "Massachusetts"
|
150
|
+
# map["GA"] = "Georgia"
|
151
|
+
# map.max #=> ["MA", "Massachusetts"]
|
152
|
+
def max
|
153
|
+
return nil if @root.nil?
|
154
|
+
n = @root
|
155
|
+
while n.right
|
156
|
+
n = n.right
|
157
|
+
end
|
158
|
+
splay(n.key)
|
159
|
+
return [n.key, n.value]
|
160
|
+
end
|
161
|
+
|
162
|
+
# Deletes the item and key if it's found, and returns the item. Returns nil
|
163
|
+
# if key is not present.
|
164
|
+
#
|
165
|
+
# Complexity: amortized O(log n)
|
166
|
+
#
|
167
|
+
# map = Algorithms::Containers::SplayTreeMap.new
|
168
|
+
# map["MA"] = "Massachusetts"
|
169
|
+
# map["GA"] = "Georgia"
|
170
|
+
# map.delete("GA") #=> "Georgia"
|
171
|
+
# map.delete("DE") #=> nil
|
172
|
+
def delete(key)
|
173
|
+
return nil if @root.nil?
|
174
|
+
deleted = nil
|
175
|
+
splay(key)
|
176
|
+
if (key <=> @root.key) == 0 # The key exists
|
177
|
+
deleted = @root.value
|
178
|
+
if @root.left.nil?
|
179
|
+
@root = @root.right
|
180
|
+
else
|
181
|
+
x = @root.right
|
182
|
+
@root = @root.left
|
183
|
+
splay(key)
|
184
|
+
@root.right = x
|
185
|
+
end
|
186
|
+
end
|
187
|
+
deleted
|
188
|
+
end
|
189
|
+
|
190
|
+
# Iterates over the SplayTreeMap in ascending order. Uses an iterative, not recursive, approach.
|
191
|
+
def each
|
192
|
+
return nil unless @root
|
193
|
+
stack = Stack.new
|
194
|
+
cursor = @root
|
195
|
+
loop do
|
196
|
+
if cursor
|
197
|
+
stack.push(cursor)
|
198
|
+
cursor = cursor.left
|
199
|
+
else
|
200
|
+
unless stack.empty?
|
201
|
+
cursor = stack.pop
|
202
|
+
yield(cursor.key, cursor.value)
|
203
|
+
cursor = cursor.right
|
204
|
+
else
|
205
|
+
break
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Moves a key to the root, updating the structure in each step.
|
212
|
+
def splay(key)
|
213
|
+
l, r = @header, @header
|
214
|
+
t = @root
|
215
|
+
@header.left, @header.right = nil, nil
|
216
|
+
|
217
|
+
loop do
|
218
|
+
if (key <=> t.key) == -1
|
219
|
+
break unless t.left
|
220
|
+
if (key <=> t.left.key) == -1
|
221
|
+
y = t.left
|
222
|
+
t.left = y.right
|
223
|
+
y.right = t
|
224
|
+
t = y
|
225
|
+
break unless t.left
|
226
|
+
end
|
227
|
+
r.left = t
|
228
|
+
r = t
|
229
|
+
t = t.left
|
230
|
+
elsif (key <=> t.key) == 1
|
231
|
+
break unless t.right
|
232
|
+
if (key <=> t.right.key) == 1
|
233
|
+
y = t.right
|
234
|
+
t.right = y.left
|
235
|
+
y.left = t
|
236
|
+
t = y
|
237
|
+
break unless t.right
|
238
|
+
end
|
239
|
+
l.right = t
|
240
|
+
l = t
|
241
|
+
t = t.right
|
242
|
+
else
|
243
|
+
break
|
244
|
+
end
|
245
|
+
end
|
246
|
+
l.right = t.left
|
247
|
+
r.left = t.right
|
248
|
+
t.left = @header.right
|
249
|
+
t.right = @header.left
|
250
|
+
@root = t
|
251
|
+
end
|
252
|
+
private :splay
|
253
|
+
|
254
|
+
# Recursively determine height
|
255
|
+
def height_recursive(node)
|
256
|
+
return 0 if node.nil?
|
257
|
+
|
258
|
+
left_height = 1 + height_recursive(node.left)
|
259
|
+
right_height = 1 + height_recursive(node.right)
|
260
|
+
|
261
|
+
left_height > right_height ? left_height : right_height
|
262
|
+
end
|
263
|
+
private :height_recursive
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
begin
|
268
|
+
require 'CSplayTreeMap'
|
269
|
+
Containers::SplayTreeMap = Containers::CSplayTreeMap
|
270
|
+
rescue # C Version could not be found, try ruby version
|
271
|
+
Containers::SplayTreeMap = Containers::RubySplayTreeMap
|
272
|
+
end
|
273
|
+
end
|