stakach-algorithms 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,421 +1,421 @@
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
- static VALUE namespace;
398
-
399
- void Init_CSplayTreeMap() {
400
- id_compare_operator = rb_intern("<=>");
401
-
402
- namespace = rb_define_module("Algorithms");
403
- mContainers = rb_define_module_under(namespace,"Containers");
404
- CSplayTree = rb_define_class_under(mContainers, "CSplayTreeMap", rb_cObject);
405
- rb_define_alloc_func(CSplayTree, splaytree_alloc);
406
- rb_define_method(CSplayTree, "initialize", splaytree_init, 0);
407
- rb_define_method(CSplayTree, "push", splaytree_push, 2);
408
- rb_define_method(CSplayTree, "clear", splaytree_clear, 0);
409
- rb_define_alias(CSplayTree, "[]=", "push");
410
- rb_define_method(CSplayTree, "size", splaytree_size, 0);
411
- rb_define_method(CSplayTree, "empty?", splaytree_is_empty, 0);
412
- rb_define_method(CSplayTree, "height", splaytree_height, 0);
413
- rb_define_method(CSplayTree, "min_key", splaytree_min_key, 0);
414
- rb_define_method(CSplayTree, "max_key", splaytree_max_key, 0);
415
- rb_define_method(CSplayTree, "each", splaytree_each, 0);
416
- rb_define_method(CSplayTree, "get", splaytree_get, 1);
417
- rb_define_alias(CSplayTree, "[]", "get");
418
- rb_define_method(CSplayTree, "has_key?", splaytree_has_key, 1);
419
- rb_define_method(CSplayTree, "delete", splaytree_delete, 1);
420
- rb_include_module(CSplayTree, rb_eval_string("Enumerable"));
421
- }
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
+ static VALUE namespace;
398
+
399
+ void Init_CSplayTreeMap() {
400
+ id_compare_operator = rb_intern("<=>");
401
+
402
+ namespace = rb_define_module("Algorithms");
403
+ mContainers = rb_define_module_under(namespace,"Containers");
404
+ CSplayTree = rb_define_class_under(mContainers, "CSplayTreeMap", rb_cObject);
405
+ rb_define_alloc_func(CSplayTree, splaytree_alloc);
406
+ rb_define_method(CSplayTree, "initialize", splaytree_init, 0);
407
+ rb_define_method(CSplayTree, "push", splaytree_push, 2);
408
+ rb_define_method(CSplayTree, "clear", splaytree_clear, 0);
409
+ rb_define_alias(CSplayTree, "[]=", "push");
410
+ rb_define_method(CSplayTree, "size", splaytree_size, 0);
411
+ rb_define_method(CSplayTree, "empty?", splaytree_is_empty, 0);
412
+ rb_define_method(CSplayTree, "height", splaytree_height, 0);
413
+ rb_define_method(CSplayTree, "min_key", splaytree_min_key, 0);
414
+ rb_define_method(CSplayTree, "max_key", splaytree_max_key, 0);
415
+ rb_define_method(CSplayTree, "each", splaytree_each, 0);
416
+ rb_define_method(CSplayTree, "get", splaytree_get, 1);
417
+ rb_define_alias(CSplayTree, "[]", "get");
418
+ rb_define_method(CSplayTree, "has_key?", splaytree_has_key, 1);
419
+ rb_define_method(CSplayTree, "delete", splaytree_delete, 1);
420
+ rb_include_module(CSplayTree, rb_eval_string("Enumerable"));
421
+ }