algorithms 0.3.0-jruby
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/History.txt +172 -0
- data/Manifest +43 -0
- data/README.markdown +93 -0
- data/Rakefile +31 -0
- data/algorithms.gemspec +33 -0
- data/benchmarks/deque.rb +17 -0
- data/benchmarks/sorts.rb +34 -0
- data/benchmarks/treemaps.rb +51 -0
- data/ext/containers/deque/deque.c +247 -0
- data/ext/containers/deque/extconf.rb +4 -0
- data/ext/containers/rbtree_map/extconf.rb +4 -0
- data/ext/containers/rbtree_map/rbtree.c +498 -0
- data/ext/containers/splaytree_map/extconf.rb +4 -0
- data/ext/containers/splaytree_map/splaytree.c +419 -0
- data/lib/algorithms.rb +68 -0
- data/lib/algorithms/search.rb +84 -0
- data/lib/algorithms/sort.rb +238 -0
- data/lib/containers/deque.rb +171 -0
- data/lib/containers/heap.rb +486 -0
- data/lib/containers/kd_tree.rb +110 -0
- data/lib/containers/priority_queue.rb +113 -0
- data/lib/containers/queue.rb +68 -0
- data/lib/containers/rb_tree_map.rb +398 -0
- data/lib/containers/splay_tree_map.rb +269 -0
- data/lib/containers/stack.rb +67 -0
- data/lib/containers/suffix_array.rb +68 -0
- data/lib/containers/trie.rb +182 -0
- data/spec/deque_gc_mark_spec.rb +18 -0
- data/spec/deque_spec.rb +108 -0
- data/spec/heap_spec.rb +126 -0
- data/spec/kd_expected_out.txt +10000 -0
- data/spec/kd_test_in.txt +10000 -0
- data/spec/kd_tree_spec.rb +34 -0
- data/spec/map_gc_mark_spec.rb +27 -0
- data/spec/priority_queue_spec.rb +75 -0
- data/spec/queue_spec.rb +61 -0
- data/spec/rb_tree_map_spec.rb +123 -0
- data/spec/search_spec.rb +28 -0
- data/spec/sort_spec.rb +28 -0
- data/spec/splay_tree_map_spec.rb +106 -0
- data/spec/stack_spec.rb +60 -0
- data/spec/suffix_array_spec.rb +40 -0
- data/spec/trie_spec.rb +59 -0
- metadata +122 -0
@@ -0,0 +1,419 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#define node_size(x) (((x)==NULL) ? 0 : ((x)->size))
|
4
|
+
|
5
|
+
/* Using http://www.link.cs.cmu.edu/link/ftp-site/splaying/top-down-size-splay.c as reference,
|
6
|
+
written by D. Sleator <sleator@cs.cmu.edu>, January 1994.
|
7
|
+
*/
|
8
|
+
|
9
|
+
typedef struct struct_splaytree_node {
|
10
|
+
VALUE key;
|
11
|
+
VALUE value;
|
12
|
+
int size;
|
13
|
+
struct struct_splaytree_node *left;
|
14
|
+
struct struct_splaytree_node *right;
|
15
|
+
} splaytree_node;
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
int (*compare_function)(VALUE key1, VALUE key2);
|
19
|
+
splaytree_node *root;
|
20
|
+
} splaytree;
|
21
|
+
|
22
|
+
typedef struct struct_ll_node {
|
23
|
+
splaytree_node *node;
|
24
|
+
struct struct_ll_node *next;
|
25
|
+
} ll_node;
|
26
|
+
|
27
|
+
static void recursively_free_nodes(splaytree_node *node) {
|
28
|
+
if(node) {
|
29
|
+
recursively_free_nodes(node->left);
|
30
|
+
recursively_free_nodes(node->right);
|
31
|
+
free(node);
|
32
|
+
}
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
|
36
|
+
static splaytree* get_tree_from_self(VALUE self) {
|
37
|
+
splaytree *tree;
|
38
|
+
Data_Get_Struct(self, splaytree, tree);
|
39
|
+
return tree;
|
40
|
+
}
|
41
|
+
|
42
|
+
static splaytree_node* splay(splaytree *tree, splaytree_node *n, VALUE key) {
|
43
|
+
int cmp, cmp2, root_size, l_size, r_size;
|
44
|
+
splaytree_node N;
|
45
|
+
splaytree_node *l, *r, *y;
|
46
|
+
|
47
|
+
if (!n) return n;
|
48
|
+
|
49
|
+
N.left = N.right = NULL;
|
50
|
+
l = r = &N;
|
51
|
+
root_size = node_size(n);
|
52
|
+
l_size = r_size = 0;
|
53
|
+
|
54
|
+
while(1) {
|
55
|
+
cmp = tree->compare_function(key, n->key);
|
56
|
+
if (cmp == -1) {
|
57
|
+
if (!n->left) break;
|
58
|
+
cmp2 = tree->compare_function(key, n->left->key);
|
59
|
+
if (cmp2 == -1) {
|
60
|
+
y = n->left;
|
61
|
+
n->left = y->right;
|
62
|
+
y->right = n;
|
63
|
+
n->size = node_size(n->left) + node_size(n->right) + 1;
|
64
|
+
n = y;
|
65
|
+
if (!n->left) break;
|
66
|
+
}
|
67
|
+
r->left = n;
|
68
|
+
r = n;
|
69
|
+
n = n->left;
|
70
|
+
r_size += 1 + node_size(r->right);
|
71
|
+
} else if (cmp == 1) {
|
72
|
+
if (!n->right) break;
|
73
|
+
cmp2 = tree->compare_function(key, n->right->key);
|
74
|
+
if (cmp2 == 1) {
|
75
|
+
y = n->right;
|
76
|
+
n->right = y->left;
|
77
|
+
y->left = n;
|
78
|
+
n->size = node_size(n->left) + node_size(n->right) + 1;
|
79
|
+
n = y;
|
80
|
+
if (!n->right) break;
|
81
|
+
}
|
82
|
+
l->right = n;
|
83
|
+
l = n;
|
84
|
+
n = n->right;
|
85
|
+
l_size += 1 + node_size(l->left);
|
86
|
+
} else {
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
l_size += node_size(n->left);
|
92
|
+
r_size += node_size(n->right);
|
93
|
+
n->size = l_size + r_size + 1;
|
94
|
+
l->right = r->left = NULL;
|
95
|
+
|
96
|
+
for (y = N.right; y != NULL; y = y->right) {
|
97
|
+
y->size = l_size;
|
98
|
+
l_size -= 1 + node_size(y->left);
|
99
|
+
}
|
100
|
+
for (y = N.left; y != NULL; y = y->left) {
|
101
|
+
y->size = r_size;
|
102
|
+
r_size -= 1 + node_size(y->right);
|
103
|
+
}
|
104
|
+
|
105
|
+
l->right = n->left;
|
106
|
+
r->left = n->right;
|
107
|
+
n->left = N.right;
|
108
|
+
n->right = N.left;
|
109
|
+
|
110
|
+
return n;
|
111
|
+
}
|
112
|
+
|
113
|
+
static int height(splaytree_node *h) {
|
114
|
+
int left_height, right_height;
|
115
|
+
|
116
|
+
if(!h) { return 0; }
|
117
|
+
|
118
|
+
left_height = 1 + height(h->left);
|
119
|
+
right_height = 1 + height(h->right);
|
120
|
+
|
121
|
+
return left_height > right_height ? left_height : right_height;
|
122
|
+
}
|
123
|
+
|
124
|
+
static splaytree* create_splaytree(int (*compare_function)(VALUE, VALUE)) {
|
125
|
+
splaytree *tree = ALLOC(splaytree);
|
126
|
+
tree->compare_function = compare_function;
|
127
|
+
tree->root = NULL;
|
128
|
+
return tree;
|
129
|
+
}
|
130
|
+
|
131
|
+
static splaytree_node* create_node(VALUE key, VALUE value) {
|
132
|
+
splaytree_node *new_node = ALLOC(splaytree_node);
|
133
|
+
new_node->key = key;
|
134
|
+
new_node->value = value;
|
135
|
+
new_node->left = NULL;
|
136
|
+
new_node->right = NULL;
|
137
|
+
return new_node;
|
138
|
+
}
|
139
|
+
|
140
|
+
static splaytree_node* insert(splaytree *tree, splaytree_node *n, VALUE key, VALUE value) {
|
141
|
+
int cmp;
|
142
|
+
splaytree_node *new_node;
|
143
|
+
|
144
|
+
if (n) {
|
145
|
+
n = splay(tree, n, key);
|
146
|
+
cmp = tree->compare_function(key, n->key);
|
147
|
+
if (cmp == 0) {
|
148
|
+
n->value = value;
|
149
|
+
return n;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
new_node = create_node(key, value);
|
153
|
+
if (!n) {
|
154
|
+
new_node->left = new_node->right = NULL;
|
155
|
+
} else {
|
156
|
+
cmp = tree->compare_function(key, n->key);
|
157
|
+
if (cmp < 0) {
|
158
|
+
new_node->left = n->left;
|
159
|
+
new_node->right = n;
|
160
|
+
n->left = NULL;
|
161
|
+
n->size = 1 + node_size(n->right);
|
162
|
+
} else {
|
163
|
+
new_node->right = n->right;
|
164
|
+
new_node->left = n;
|
165
|
+
n->right = NULL;
|
166
|
+
n->size = 1 + node_size(n->left);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
new_node->size = 1 + node_size(new_node->left) + node_size(new_node->right);
|
170
|
+
return new_node;
|
171
|
+
}
|
172
|
+
|
173
|
+
static VALUE get(splaytree *tree, VALUE key) {
|
174
|
+
int cmp;
|
175
|
+
|
176
|
+
if (!tree->root)
|
177
|
+
return Qnil;
|
178
|
+
|
179
|
+
tree->root = splay(tree, tree->root, key);
|
180
|
+
cmp = tree->compare_function(key, tree->root->key);
|
181
|
+
if (cmp == 0) {
|
182
|
+
return tree->root->value;
|
183
|
+
}
|
184
|
+
return Qnil;
|
185
|
+
}
|
186
|
+
|
187
|
+
static splaytree_node* delete(splaytree *tree, splaytree_node *n, VALUE key, VALUE *deleted) {
|
188
|
+
int cmp, tsize;
|
189
|
+
splaytree_node *x;
|
190
|
+
|
191
|
+
tsize = n->size;
|
192
|
+
n = splay(tree, n, key);
|
193
|
+
cmp = tree->compare_function(key, n->key);
|
194
|
+
if (cmp == 0) {
|
195
|
+
*deleted = n->value;
|
196
|
+
if (!n->left) {
|
197
|
+
x = n->right;
|
198
|
+
} else {
|
199
|
+
x = splay(tree, n->left, key);
|
200
|
+
x->right = n->right;
|
201
|
+
}
|
202
|
+
free(n);
|
203
|
+
if (x) {
|
204
|
+
x->size = tsize-1;
|
205
|
+
}
|
206
|
+
return x;
|
207
|
+
}
|
208
|
+
return n;
|
209
|
+
}
|
210
|
+
|
211
|
+
static splaytree* splaytree_each_node(splaytree *tree, splaytree_node *node, void (*each)(splaytree *tree_, splaytree_node *node_, void* args), void* arguments) {
|
212
|
+
if (!node)
|
213
|
+
return NULL;
|
214
|
+
|
215
|
+
if (node->left)
|
216
|
+
splaytree_each_node(tree, node->left, each, arguments);
|
217
|
+
|
218
|
+
(*each)(tree, node, arguments);
|
219
|
+
|
220
|
+
if (node->right)
|
221
|
+
splaytree_each_node(tree, node->right, each, arguments);
|
222
|
+
return tree;
|
223
|
+
}
|
224
|
+
|
225
|
+
static splaytree* splay_each(splaytree *tree, void (*each)(splaytree *tree, splaytree_node *node, void *args), void* arguments) {
|
226
|
+
if (tree->root)
|
227
|
+
splaytree_each_node(tree, tree->root, each, arguments);
|
228
|
+
return tree;
|
229
|
+
}
|
230
|
+
|
231
|
+
// Methods to be called in Ruby
|
232
|
+
|
233
|
+
static int id_compare_operator;
|
234
|
+
|
235
|
+
static int splaytree_compare_function(VALUE a, VALUE b) {
|
236
|
+
if (a == b) return 0;
|
237
|
+
if (FIXNUM_P(a) && FIXNUM_P(b)) {
|
238
|
+
long x = FIX2LONG(a), y = FIX2LONG(b);
|
239
|
+
if (x == y) return 0;
|
240
|
+
if (x > y) return 1;
|
241
|
+
return -1;
|
242
|
+
}
|
243
|
+
if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
|
244
|
+
TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
|
245
|
+
return rb_str_cmp(a, b);
|
246
|
+
}
|
247
|
+
return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
|
248
|
+
}
|
249
|
+
|
250
|
+
static VALUE splaytree_init(VALUE self)
|
251
|
+
{
|
252
|
+
return self;
|
253
|
+
}
|
254
|
+
|
255
|
+
static void splaytree_mark(void *ptr) {
|
256
|
+
ll_node *current, *new, *last, *old;
|
257
|
+
if (ptr) {
|
258
|
+
splaytree *tree = ptr;
|
259
|
+
|
260
|
+
if (tree->root) {
|
261
|
+
current = ALLOC(ll_node);
|
262
|
+
last = current;
|
263
|
+
current->node = tree->root;
|
264
|
+
current->next = NULL;
|
265
|
+
|
266
|
+
while(current) {
|
267
|
+
rb_gc_mark(current->node->key);
|
268
|
+
rb_gc_mark(current->node->value);
|
269
|
+
if (current->node->left) {
|
270
|
+
new = ALLOC(ll_node);
|
271
|
+
new->node = current->node->left;
|
272
|
+
new->next = NULL;
|
273
|
+
last->next = new;
|
274
|
+
last = new;
|
275
|
+
}
|
276
|
+
if (current->node->right) {
|
277
|
+
new = ALLOC(ll_node);
|
278
|
+
new->node = current->node->right;
|
279
|
+
new->next = NULL;
|
280
|
+
last->next = new;
|
281
|
+
last = new;
|
282
|
+
}
|
283
|
+
old = current;
|
284
|
+
current = current->next;
|
285
|
+
free(old);
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
291
|
+
static void splaytree_free(void *ptr) {
|
292
|
+
if (ptr) {
|
293
|
+
splaytree *tree = ptr;
|
294
|
+
recursively_free_nodes(tree->root);
|
295
|
+
free(tree);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
|
299
|
+
static VALUE splaytree_alloc(VALUE klass) {
|
300
|
+
splaytree *tree = create_splaytree(&splaytree_compare_function);
|
301
|
+
return Data_Wrap_Struct(klass, splaytree_mark, splaytree_free, tree);
|
302
|
+
}
|
303
|
+
|
304
|
+
static VALUE splaytree_push(VALUE self, VALUE key, VALUE value) {
|
305
|
+
splaytree *tree = get_tree_from_self(self);
|
306
|
+
tree->root = insert(tree, tree->root, key, value);
|
307
|
+
return value;
|
308
|
+
}
|
309
|
+
|
310
|
+
static VALUE splaytree_get(VALUE self, VALUE key) {
|
311
|
+
splaytree *tree = get_tree_from_self(self);
|
312
|
+
return get(tree, key);
|
313
|
+
}
|
314
|
+
|
315
|
+
static VALUE splaytree_size(VALUE self) {
|
316
|
+
splaytree *tree = get_tree_from_self(self);
|
317
|
+
if(!tree->root) { return INT2NUM(0); }
|
318
|
+
return INT2NUM(tree->root->size);
|
319
|
+
}
|
320
|
+
|
321
|
+
static VALUE splaytree_is_empty(VALUE self) {
|
322
|
+
splaytree *tree = get_tree_from_self(self);
|
323
|
+
return (tree->root ? Qfalse : Qtrue);
|
324
|
+
}
|
325
|
+
|
326
|
+
static VALUE splaytree_height(VALUE self) {
|
327
|
+
splaytree *tree = get_tree_from_self(self);
|
328
|
+
return INT2NUM(height(tree->root));
|
329
|
+
}
|
330
|
+
|
331
|
+
static VALUE splaytree_has_key(VALUE self, VALUE key) {
|
332
|
+
splaytree *tree = get_tree_from_self(self);
|
333
|
+
if(!tree->root) { return Qfalse; }
|
334
|
+
if(get(tree, key) == Qnil)
|
335
|
+
return Qfalse;
|
336
|
+
|
337
|
+
return Qtrue;
|
338
|
+
}
|
339
|
+
|
340
|
+
static VALUE splaytree_min_key(VALUE self) {
|
341
|
+
splaytree *tree = get_tree_from_self(self);
|
342
|
+
splaytree_node *node;
|
343
|
+
|
344
|
+
if(!tree->root)
|
345
|
+
return Qnil;
|
346
|
+
|
347
|
+
node = tree->root;
|
348
|
+
while (node->left)
|
349
|
+
node = node->left;
|
350
|
+
|
351
|
+
return node->key;
|
352
|
+
}
|
353
|
+
|
354
|
+
static VALUE splaytree_max_key(VALUE self) {
|
355
|
+
splaytree *tree = get_tree_from_self(self);
|
356
|
+
splaytree_node *node;
|
357
|
+
|
358
|
+
if(!tree->root)
|
359
|
+
return Qnil;
|
360
|
+
|
361
|
+
node = tree->root;
|
362
|
+
while (node->right)
|
363
|
+
node = node->right;
|
364
|
+
|
365
|
+
return node->key;
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE splaytree_delete(VALUE self, VALUE key) {
|
369
|
+
VALUE deleted = Qnil;
|
370
|
+
splaytree *tree = get_tree_from_self(self);
|
371
|
+
if(!tree->root)
|
372
|
+
return Qnil;
|
373
|
+
|
374
|
+
tree->root = delete(tree, tree->root, key, &deleted);
|
375
|
+
return deleted;
|
376
|
+
}
|
377
|
+
|
378
|
+
static VALUE splaytree_clear(VALUE self) {
|
379
|
+
splaytree *tree = get_tree_from_self(self);
|
380
|
+
recursively_free_nodes(tree->root);
|
381
|
+
tree->root = NULL;
|
382
|
+
return Qnil;
|
383
|
+
}
|
384
|
+
|
385
|
+
static void splaytree_each_helper(splaytree *tree, splaytree_node *node, void *args) {
|
386
|
+
rb_yield(rb_ary_new3(2, node->key, node->value));
|
387
|
+
};
|
388
|
+
|
389
|
+
static VALUE splaytree_each(VALUE self) {
|
390
|
+
splaytree *tree = get_tree_from_self(self);
|
391
|
+
splay_each(tree, &splaytree_each_helper, NULL);
|
392
|
+
return self;
|
393
|
+
}
|
394
|
+
|
395
|
+
static VALUE CSplayTree;
|
396
|
+
static VALUE mContainers;
|
397
|
+
|
398
|
+
void Init_CSplayTreeMap() {
|
399
|
+
id_compare_operator = rb_intern("<=>");
|
400
|
+
|
401
|
+
mContainers = rb_define_module("Containers");
|
402
|
+
CSplayTree = rb_define_class_under(mContainers, "CSplayTreeMap", rb_cObject);
|
403
|
+
rb_define_alloc_func(CSplayTree, splaytree_alloc);
|
404
|
+
rb_define_method(CSplayTree, "initialize", splaytree_init, 0);
|
405
|
+
rb_define_method(CSplayTree, "push", splaytree_push, 2);
|
406
|
+
rb_define_method(CSplayTree, "clear", splaytree_clear, 0);
|
407
|
+
rb_define_alias(CSplayTree, "[]=", "push");
|
408
|
+
rb_define_method(CSplayTree, "size", splaytree_size, 0);
|
409
|
+
rb_define_method(CSplayTree, "empty?", splaytree_is_empty, 0);
|
410
|
+
rb_define_method(CSplayTree, "height", splaytree_height, 0);
|
411
|
+
rb_define_method(CSplayTree, "min_key", splaytree_min_key, 0);
|
412
|
+
rb_define_method(CSplayTree, "max_key", splaytree_max_key, 0);
|
413
|
+
rb_define_method(CSplayTree, "each", splaytree_each, 0);
|
414
|
+
rb_define_method(CSplayTree, "get", splaytree_get, 1);
|
415
|
+
rb_define_alias(CSplayTree, "[]", "get");
|
416
|
+
rb_define_method(CSplayTree, "has_key?", splaytree_has_key, 1);
|
417
|
+
rb_define_method(CSplayTree, "delete", splaytree_delete, 1);
|
418
|
+
rb_include_module(CSplayTree, rb_eval_string("Enumerable"));
|
419
|
+
}
|
data/lib/algorithms.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
The 'Algorithms and Containers' library is an effort to provide a set of commonly used
|
3
|
+
algorithms and containers to Ruby programmers.
|
4
|
+
|
5
|
+
This is a Google Summer of Code 2008 project
|
6
|
+
|
7
|
+
Written by Kanwei Li, mentored by Austin Ziegler
|
8
|
+
|
9
|
+
To avoid typing Containers::xxx to initialize containers, include the Containers module.
|
10
|
+
|
11
|
+
require 'algorithms'
|
12
|
+
include Containers
|
13
|
+
|
14
|
+
tree = RBTreeMap.new
|
15
|
+
|
16
|
+
instead of:
|
17
|
+
|
18
|
+
require 'algorithms'
|
19
|
+
|
20
|
+
tree = Containers::RBTreeMap.new
|
21
|
+
|
22
|
+
Done so far:
|
23
|
+
* Heaps - Containers::Heap, Containers::MaxHeap, Containers::MinHeap
|
24
|
+
* Priority Queue - Containers::PriorityQueue
|
25
|
+
* Stack - Containers::Stack
|
26
|
+
* Queue - Containers::Queue
|
27
|
+
* Deque - Containers::Deque, Containers::CDeque (C extension), Containers::RubyDeque
|
28
|
+
* Red-Black Trees - Containers::RBTreeMap, Containers::CRBTreeMap (C extension), Containers::RubyRBTreeMap
|
29
|
+
* Splay Trees - Containers::SplayTreeMap
|
30
|
+
* Tries - Containers::Trie
|
31
|
+
* Suffix Array - Containers::SuffixArray
|
32
|
+
* kd Tree - Containers::KDTree
|
33
|
+
|
34
|
+
* Search algorithms
|
35
|
+
- Binary Search - Algorithms::Search.binary_search
|
36
|
+
- Knuth-Morris-Pratt - Algorithms::Search.kmp_search
|
37
|
+
* Sort algorithms
|
38
|
+
- Bubble sort - Algorithms::Sort.bubble_sort
|
39
|
+
- Comb sort - Algorithms::Sort.comb_sort
|
40
|
+
- Selection sort - Algorithms::Sort.selection_sort
|
41
|
+
- Heapsort - Algorithms::Sort.heapsort
|
42
|
+
- Insertion sort - Algorithms::Sort.insertion_sort
|
43
|
+
- Shell sort - Algorithms::Sort.shell_sort
|
44
|
+
- Quicksort - Algorithms::Sort.quicksort
|
45
|
+
- Mergesort - Algorithms::Sort.mergesort
|
46
|
+
=end
|
47
|
+
|
48
|
+
module Algorithms; end
|
49
|
+
module Containers; end
|
50
|
+
|
51
|
+
begin
|
52
|
+
require 'CBst'
|
53
|
+
Containers::Bst = Containers::CBst
|
54
|
+
rescue LoadError # C Version could not be found
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'algorithms/search'
|
58
|
+
require 'algorithms/sort'
|
59
|
+
require 'containers/heap'
|
60
|
+
require 'containers/stack'
|
61
|
+
require 'containers/deque'
|
62
|
+
require 'containers/queue'
|
63
|
+
require 'containers/priority_queue'
|
64
|
+
require 'containers/rb_tree_map'
|
65
|
+
require 'containers/splay_tree_map'
|
66
|
+
require 'containers/suffix_array'
|
67
|
+
require 'containers/trie'
|
68
|
+
require 'containers/kd_tree'
|