algorithms 0.2.0 → 1.0.0

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.
@@ -0,0 +1,247 @@
1
+ #include "ruby.h"
2
+
3
+ typedef struct struct_bst_node {
4
+ VALUE key;
5
+ VALUE value;
6
+ struct struct_bst_node *left;
7
+ struct struct_bst_node *right;
8
+ struct struct_bst_node *parent;
9
+ } bst_node;
10
+
11
+ typedef struct struct_bst {
12
+ bst_node *root;
13
+ int (*compare_function)(VALUE key1, VALUE key2);
14
+ unsigned int size;
15
+ } bst;
16
+
17
+ static VALUE bst_initialize(VALUE self) {
18
+ return self;
19
+ }
20
+
21
+ static bst* get_bst_from_self(VALUE self) {
22
+ bst *tree;
23
+ Data_Get_Struct(self, bst, tree);
24
+ return tree;
25
+ }
26
+
27
+ static bst* bst_each_node(bst *tree, bst_node *node, void (*each)(bst *tree_, bst_node *node_, void* args), void* arguments) {
28
+ if (!node)
29
+ return NULL;
30
+
31
+ if (node->left)
32
+ bst_each_node(tree, node->left, each, arguments);
33
+
34
+ (*each)(tree, node, arguments);
35
+
36
+ if (node->right)
37
+ bst_each_node(tree, node->right, each, arguments);
38
+ return tree;
39
+ }
40
+
41
+ static bst* bst_each(bst *tree, void (*each)(bst *tree, bst_node *node, void *args), void* arguments) {
42
+ if (tree->root)
43
+ bst_each_node(tree, tree->root, each, arguments);
44
+ return tree;
45
+ }
46
+
47
+ static VALUE id_compare_operator;
48
+
49
+ static int bst_compare_function(VALUE a, VALUE b) {
50
+ if (a == b) return 0;
51
+ if (FIXNUM_P(a) && FIXNUM_P(b)) {
52
+ long x = FIX2LONG(a), y = FIX2LONG(b);
53
+ if (x == y) return 0;
54
+ if (x > y) return 1;
55
+ return -1;
56
+ }
57
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
58
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
59
+ return rb_str_cmp(a, b);
60
+ }
61
+ return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
62
+ }
63
+
64
+ static void insert_element(bst *tree, bst_node **t,bst_node *newElement) {
65
+ int cmp;
66
+ bst_node *y = NULL;
67
+ bst_node *x = *t;
68
+ while (x != NULL) {
69
+ y = x;
70
+ cmp = tree->compare_function(newElement->key, x->key);
71
+ if (cmp < 0) x = x->left;
72
+ else x = x->right;
73
+ }
74
+ newElement->parent = y;
75
+ if (y == NULL) *t = newElement;
76
+ else {
77
+ cmp = tree->compare_function(newElement->key, y->key);
78
+ if (cmp < 0)
79
+ y->left = newElement;
80
+ else
81
+ y->right = newElement;
82
+ }
83
+ }
84
+
85
+
86
+ static bst_node* create_node(VALUE key_value,VALUE value) {
87
+ bst_node *new_node = ALLOC(bst_node);
88
+ new_node->value = value;
89
+ new_node->key = key_value;
90
+ new_node->left = NULL;
91
+ new_node->right = NULL;
92
+ new_node->parent = NULL;
93
+ return new_node;
94
+ }
95
+
96
+ static bst_node* tree_minimum (bst_node *tree) {
97
+ bst_node *x = tree;
98
+ while (x->left) x = x->left;
99
+ return x;
100
+ }
101
+
102
+ static bst_node* tree_maximum (bst_node *tree) {
103
+ bst_node *x = tree;
104
+ while (x->right) x = x->right;
105
+ return x;
106
+ }
107
+
108
+ static bst_node* node_successor (bst_node *tree,bst_node *x) {
109
+ if (x->right) return tree_minimum(x->right);
110
+ bst_node *y = x->parent;
111
+ while (y && x == y->right) {
112
+ x = y;
113
+ y = x->parent;
114
+ }
115
+ return y;
116
+ }
117
+
118
+
119
+ static bst_node* delete_node (bst_node **tree,bst_node *tobeDeleted) {
120
+ bst_node *y,*x;
121
+
122
+ if ((tobeDeleted->left == NULL) || (tobeDeleted->right == NULL)) y = tobeDeleted;
123
+ else y = node_successor(*tree,tobeDeleted);
124
+
125
+ if (y->left) x = y->left;
126
+ else x = y->right;
127
+
128
+ if (x) x->parent = y->parent;
129
+
130
+ if (y->parent == NULL) {
131
+ *tree = x;
132
+ return y;
133
+ } else if (y == y->parent->left) {
134
+ y->parent->left = x;
135
+ } else {
136
+ y->parent->right = x;
137
+ }
138
+
139
+ if (tobeDeleted != y) tobeDeleted->key = y->key;
140
+ return y;
141
+ }
142
+
143
+ static bst_node* search_node(bst *tree, bst_node *node, VALUE key) {
144
+ bst_node *x = node;
145
+ int cmp;
146
+
147
+ while(x) {
148
+ cmp = tree->compare_function(key, x->key);
149
+ if (cmp == 0) return x;
150
+ else if (cmp < 0) { x = x->left; }
151
+ else { x = x->right; }
152
+ }
153
+ return NULL;
154
+ }
155
+
156
+ static void recursively_mark_nodes(bst_node *node) {
157
+ if(node) {
158
+ rb_gc_mark(node->key);
159
+ rb_gc_mark(node->value);
160
+ recursively_mark_nodes(node->left);
161
+ recursively_mark_nodes(node->right);
162
+ }
163
+ }
164
+
165
+ static void bst_mark(bst *tree) {
166
+ if (tree) {
167
+ recursively_mark_nodes(tree->root);
168
+ }
169
+ }
170
+
171
+ static void recursively_free_nodes(bst_node *node) {
172
+ if(node) {
173
+ recursively_free_nodes(node->left);
174
+ recursively_free_nodes(node->right);
175
+ xfree(node);
176
+ }
177
+ }
178
+
179
+ static void bst_free(bst *tree) {
180
+ if (tree) {
181
+ recursively_free_nodes(tree->root);
182
+ }
183
+ }
184
+
185
+ static bst* create_bst(int (*compare_function)(VALUE, VALUE)) {
186
+ bst *tree = ALLOC(bst);
187
+ tree->compare_function = compare_function;
188
+ tree->root = NULL;
189
+ tree->size = 0;
190
+ return tree;
191
+ }
192
+
193
+ static VALUE bst_alloc(VALUE klass) {
194
+ bst *tree = create_bst(&bst_compare_function);
195
+ return Data_Wrap_Struct(klass, bst_mark, bst_free, tree);
196
+ }
197
+
198
+ static VALUE rb_bst_push_value(VALUE self, VALUE key, VALUE value) {
199
+ bst *tree = get_bst_from_self(self);
200
+ insert_element(tree, &(tree->root), create_node(key,value));
201
+ tree->size++;
202
+ return self;
203
+ }
204
+
205
+ static void bst_each_helper(bst *tree, bst_node *node, void *args) {
206
+ rb_yield(rb_ary_new3(2, node->key, node->value));
207
+ };
208
+
209
+ static VALUE rb_bst_each(VALUE self) {
210
+ bst *tree = get_bst_from_self(self);
211
+ bst_each(tree, &bst_each_helper, NULL);
212
+ return self;
213
+ }
214
+
215
+ static VALUE rb_bst_delete(VALUE self, VALUE key) {
216
+ bst *tree = get_bst_from_self(self);
217
+ bst_node *tobeDeleted = search_node(tree, tree->root, key);
218
+ if(tobeDeleted) {
219
+ tree->size -= 1;
220
+ bst_node *deletedNode = delete_node(&(tree->root),tobeDeleted);
221
+ return deletedNode->value;
222
+ }
223
+ return Qnil;
224
+ }
225
+
226
+ static VALUE rb_bst_size(VALUE self) {
227
+ bst *tree;
228
+ Data_Get_Struct(self,bst,tree);
229
+ return INT2FIX(tree->size);
230
+ }
231
+
232
+ static VALUE CBst;
233
+ static VALUE mContainers;
234
+
235
+ void Init_CBst() {
236
+ id_compare_operator = rb_intern("<=>");
237
+
238
+ mContainers = rb_define_module("Containers");
239
+ CBst = rb_define_class_under(mContainers, "CBst", rb_cObject);
240
+ rb_define_alloc_func(CBst, bst_alloc);
241
+ rb_define_method(CBst, "initialize", bst_initialize, 0);
242
+ rb_define_method(CBst, "push", rb_bst_push_value, 2);
243
+ rb_define_alias(CBst, "[]=", "push");
244
+ rb_define_method(CBst, "each", rb_bst_each, 0);
245
+ rb_define_method(CBst, "delete", rb_bst_delete, 1);
246
+ rb_define_method(CBst, "size", rb_bst_size, 0);
247
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+ extension_name = "CBst"
3
+ dir_config(extension_name)
4
+ create_makefile(extension_name)
@@ -19,7 +19,7 @@ void free_nodes(deque_node *node) {
19
19
  deque_node *next;
20
20
  while(node) {
21
21
  next = node->right;
22
- free(node);
22
+ xfree(node);
23
23
  node = next;
24
24
  }
25
25
  return;
@@ -71,7 +71,7 @@ static void deque_free(void *ptr) {
71
71
  if (ptr) {
72
72
  deque *deque = ptr;
73
73
  free_nodes(deque->front);
74
- free(deque);
74
+ xfree(deque);
75
75
  }
76
76
  }
77
77
 
@@ -200,7 +200,7 @@ static VALUE deque_each_backward(VALUE self) {
200
200
 
201
201
  static VALUE deque_init(int argc, VALUE *argv, VALUE self)
202
202
  {
203
- int len, i;
203
+ long len, i;
204
204
  VALUE ary;
205
205
 
206
206
  if(argc == 0) {
@@ -22,11 +22,16 @@ typedef struct {
22
22
  rbtree_node *root;
23
23
  } rbtree;
24
24
 
25
+ typedef struct struct_ll_node {
26
+ rbtree_node *node;
27
+ struct struct_ll_node *next;
28
+ } ll_node;
29
+
25
30
  static void recursively_free_nodes(rbtree_node *node) {
26
31
  if(node) {
27
32
  recursively_free_nodes(node->left);
28
33
  recursively_free_nodes(node->right);
29
- free(node);
34
+ xfree(node);
30
35
  }
31
36
  return;
32
37
  }
@@ -193,7 +198,7 @@ static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) {
193
198
  if ( !h->left ) {
194
199
  if(deleted_value)
195
200
  *deleted_value = h->value;
196
- free(h);
201
+ xfree(h);
197
202
  return NULL;
198
203
  }
199
204
 
@@ -211,7 +216,7 @@ static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) {
211
216
 
212
217
  if ( !h->right ) {
213
218
  *deleted_value = h->value;
214
- free(h);
219
+ xfree(h);
215
220
  return NULL;
216
221
  }
217
222
 
@@ -240,7 +245,7 @@ static rbtree_node* delete(rbtree *tree, rbtree_node *node, VALUE key, VALUE *de
240
245
  cmp = tree->compare_function(key, node->key);
241
246
  if ( (cmp == 0) && !node->right ) {
242
247
  *deleted_value = node->value;
243
- free(node);
248
+ xfree(node);
244
249
  return NULL;
245
250
  }
246
251
 
@@ -282,7 +287,7 @@ static rbtree* rbt_each(rbtree *tree, void (*each)(rbtree *tree, rbtree_node *no
282
287
 
283
288
  // Methods to be called in Ruby
284
289
 
285
- static int id_compare_operator;
290
+ static VALUE id_compare_operator;
286
291
 
287
292
  static int rbtree_compare_function(VALUE a, VALUE b) {
288
293
  if (a == b) return 0;
@@ -292,8 +297,8 @@ static int rbtree_compare_function(VALUE a, VALUE b) {
292
297
  if (x > y) return 1;
293
298
  return -1;
294
299
  }
295
- if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
296
- TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
300
+ if (TYPE(a) == T_STRING && rb_obj_is_kind_of(a, rb_cString) &&
301
+ TYPE(b) == T_STRING && rb_obj_is_kind_of(b, rb_cString)) {
297
302
  return rb_str_cmp(a, b);
298
303
  }
299
304
  return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
@@ -304,19 +309,39 @@ static VALUE rbtree_init(VALUE self)
304
309
  return self;
305
310
  }
306
311
 
307
- static void recursively_mark_nodes(rbtree_node *node) {
308
- if(node) {
309
- rb_gc_mark(node->key);
310
- rb_gc_mark(node->value);
311
- recursively_mark_nodes(node->left);
312
- recursively_mark_nodes(node->right);
313
- }
314
- }
315
-
316
312
  static void rbtree_mark(void *ptr) {
313
+ ll_node *current, *new, *last, *old;
317
314
  if (ptr) {
318
315
  rbtree *tree = ptr;
319
- recursively_mark_nodes(tree->root);
316
+
317
+ if (tree->root) {
318
+ current = ALLOC(ll_node);
319
+ last = current;
320
+ current->node = tree->root;
321
+ current->next = NULL;
322
+
323
+ while(current) {
324
+ rb_gc_mark(current->node->key);
325
+ rb_gc_mark(current->node->value);
326
+ if (current->node->left) {
327
+ new = ALLOC(ll_node);
328
+ new->node = current->node->left;
329
+ new->next = NULL;
330
+ last->next = new;
331
+ last = new;
332
+ }
333
+ if (current->node->right) {
334
+ new = ALLOC(ll_node);
335
+ new->node = current->node->right;
336
+ new->next = NULL;
337
+ last->next = new;
338
+ last = new;
339
+ }
340
+ old = current;
341
+ current = current->next;
342
+ xfree(old);
343
+ }
344
+ }
320
345
  }
321
346
  }
322
347
 
@@ -324,7 +349,7 @@ static void rbtree_free(void *ptr) {
324
349
  if (ptr) {
325
350
  rbtree *tree = ptr;
326
351
  recursively_free_nodes(tree->root);
327
- free(tree);
352
+ xfree(tree);
328
353
  }
329
354
  }
330
355
 
@@ -1,24 +1,34 @@
1
1
  #include "ruby.h"
2
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
+
3
9
  typedef struct struct_splaytree_node {
4
10
  VALUE key;
5
11
  VALUE value;
12
+ int size;
6
13
  struct struct_splaytree_node *left;
7
14
  struct struct_splaytree_node *right;
8
15
  } splaytree_node;
9
16
 
10
17
  typedef struct {
11
18
  int (*compare_function)(VALUE key1, VALUE key2);
12
- int size;
13
19
  splaytree_node *root;
14
- splaytree_node *header;
15
20
  } splaytree;
16
21
 
22
+ typedef struct struct_ll_node {
23
+ splaytree_node *node;
24
+ struct struct_ll_node *next;
25
+ } ll_node;
26
+
17
27
  static void recursively_free_nodes(splaytree_node *node) {
18
28
  if(node) {
19
29
  recursively_free_nodes(node->left);
20
30
  recursively_free_nodes(node->right);
21
- free(node);
31
+ xfree(node);
22
32
  }
23
33
  return;
24
34
  }
@@ -29,55 +39,75 @@ static splaytree* get_tree_from_self(VALUE self) {
29
39
  return tree;
30
40
  }
31
41
 
32
- static void splay(splaytree *tree, VALUE key) {
33
- int cmp, cmp2;
34
- splaytree_node *l, *r, *t, *y;
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;
35
46
 
36
- l = tree->header;
37
- r = tree->header;
38
- t = tree->root;
47
+ if (!n) return n;
39
48
 
40
- tree->header->left = NULL;
41
- tree->header->right = NULL;
49
+ N.left = N.right = NULL;
50
+ l = r = &N;
51
+ root_size = node_size(n);
52
+ l_size = r_size = 0;
42
53
 
43
54
  while(1) {
44
- cmp = tree->compare_function(key, t->key);
55
+ cmp = tree->compare_function(key, n->key);
45
56
  if (cmp == -1) {
46
- if (!(t->left)) break;
47
- cmp2 = tree->compare_function(key, t->left->key);
57
+ if (!n->left) break;
58
+ cmp2 = tree->compare_function(key, n->left->key);
48
59
  if (cmp2 == -1) {
49
- y = t->left;
50
- t->left = y->right;
51
- y->right = t;
52
- t = y;
53
- if (!(t->left)) break;
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;
54
66
  }
55
- r->left = t;
56
- r = t;
57
- t = t->left;
58
- }
59
- else if (cmp == 1) {
60
- if (!(t->right)) break;
61
- cmp2 = tree->compare_function(key, t->right->key);
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);
62
74
  if (cmp2 == 1) {
63
- y = t->right;
64
- t->right = y->left;
65
- y->left = t;
66
- t = y;
67
- if (!(t->right)) break;
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;
68
81
  }
69
- l->right = t;
70
- l = t;
71
- t = t->right;
82
+ l->right = n;
83
+ l = n;
84
+ n = n->right;
85
+ l_size += 1 + node_size(l->left);
72
86
  } else {
73
87
  break;
74
88
  }
75
89
  }
76
- l->right = t->left;
77
- r->left = t->right;
78
- t->left = tree->header->right;
79
- t->right = tree->header->left;
80
- tree->root = t;
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;
81
111
  }
82
112
 
83
113
  static int height(splaytree_node *h) {
@@ -95,8 +125,6 @@ static splaytree* create_splaytree(int (*compare_function)(VALUE, VALUE)) {
95
125
  splaytree *tree = ALLOC(splaytree);
96
126
  tree->compare_function = compare_function;
97
127
  tree->root = NULL;
98
- tree->size = 0;
99
- tree->header = ALLOC(splaytree_node);
100
128
  return tree;
101
129
  }
102
130
 
@@ -109,44 +137,46 @@ static splaytree_node* create_node(VALUE key, VALUE value) {
109
137
  return new_node;
110
138
  }
111
139
 
112
- static void insert(splaytree *tree, VALUE key, VALUE value) {
140
+ static splaytree_node* insert(splaytree *tree, splaytree_node *n, VALUE key, VALUE value) {
113
141
  int cmp;
114
142
  splaytree_node *new_node;
115
143
 
116
- if (!(tree->root)) {
117
- new_node = create_node(key, value);
118
- tree->root = new_node;
119
- tree->size += 1;
120
- return;
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
+ }
121
151
  }
122
-
123
- splay(tree, key);
124
- cmp = tree->compare_function(key, tree->root->key);
125
- if (cmp == 0) {
126
- tree->root->value = value;
127
- return;
152
+ new_node = create_node(key, value);
153
+ if (!n) {
154
+ new_node->left = new_node->right = NULL;
128
155
  } else {
129
- new_node = create_node(key, value);
130
- if (cmp == -1) {
131
- new_node->left = tree->root->left;
132
- new_node->right = tree->root;
133
- tree->root->left = NULL;
134
- } else { /* cmp == 1 */
135
- new_node->right = tree->root->right;
136
- new_node->left = tree->root;
137
- tree->root->right = NULL;
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);
138
167
  }
139
- tree->root = new_node;
140
- tree->size += 1;
141
168
  }
169
+ new_node->size = 1 + node_size(new_node->left) + node_size(new_node->right);
170
+ return new_node;
142
171
  }
143
172
 
144
173
  static VALUE get(splaytree *tree, VALUE key) {
145
174
  int cmp;
175
+
146
176
  if (!tree->root)
147
177
  return Qnil;
148
-
149
- splay(tree, key);
178
+
179
+ tree->root = splay(tree, tree->root, key);
150
180
  cmp = tree->compare_function(key, tree->root->key);
151
181
  if (cmp == 0) {
152
182
  return tree->root->value;
@@ -154,29 +184,28 @@ static VALUE get(splaytree *tree, VALUE key) {
154
184
  return Qnil;
155
185
  }
156
186
 
157
- static VALUE delete(splaytree *tree, VALUE key) {
158
- int cmp;
159
- splaytree_node *x, *deleted_root;
160
- VALUE deleted;
161
-
162
- splay(tree, key);
163
- cmp = tree->compare_function(key, tree->root->key);
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);
164
194
  if (cmp == 0) {
165
- deleted = tree->root->value;
166
- deleted_root = tree->root;
167
- if (!(tree->root->left)) {
168
- tree->root = tree->root->right;
195
+ *deleted = n->value;
196
+ if (!n->left) {
197
+ x = n->right;
169
198
  } else {
170
- x = tree->root->right;
171
- tree->root = tree->root->left;
172
- splay(tree, key);
173
- tree->root->right = x;
199
+ x = splay(tree, n->left, key);
200
+ x->right = n->right;
174
201
  }
175
- free(deleted_root);
176
- tree->size -= 1;
177
- return deleted;
202
+ xfree(n);
203
+ if (x) {
204
+ x->size = tsize-1;
205
+ }
206
+ return x;
178
207
  }
179
- return Qnil;
208
+ return n;
180
209
  }
181
210
 
182
211
  static splaytree* splaytree_each_node(splaytree *tree, splaytree_node *node, void (*each)(splaytree *tree_, splaytree_node *node_, void* args), void* arguments) {
@@ -201,7 +230,7 @@ static splaytree* splay_each(splaytree *tree, void (*each)(splaytree *tree, spla
201
230
 
202
231
  // Methods to be called in Ruby
203
232
 
204
- static int id_compare_operator;
233
+ static VALUE id_compare_operator;
205
234
 
206
235
  static int splaytree_compare_function(VALUE a, VALUE b) {
207
236
  if (a == b) return 0;
@@ -211,8 +240,8 @@ static int splaytree_compare_function(VALUE a, VALUE b) {
211
240
  if (x > y) return 1;
212
241
  return -1;
213
242
  }
214
- if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
215
- TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
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)) {
216
245
  return rb_str_cmp(a, b);
217
246
  }
218
247
  return FIX2INT(rb_funcall((VALUE) a, id_compare_operator, 1, (VALUE) b));
@@ -223,19 +252,39 @@ static VALUE splaytree_init(VALUE self)
223
252
  return self;
224
253
  }
225
254
 
226
- static void recursively_mark_nodes(splaytree_node *node) {
227
- if(node) {
228
- rb_gc_mark(node->key);
229
- rb_gc_mark(node->value);
230
- recursively_mark_nodes(node->left);
231
- recursively_mark_nodes(node->right);
232
- }
233
- }
234
-
235
255
  static void splaytree_mark(void *ptr) {
256
+ ll_node *current, *new, *last, *old;
236
257
  if (ptr) {
237
258
  splaytree *tree = ptr;
238
- recursively_mark_nodes(tree->root);
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
+ xfree(old);
286
+ }
287
+ }
239
288
  }
240
289
  }
241
290
 
@@ -243,8 +292,7 @@ static void splaytree_free(void *ptr) {
243
292
  if (ptr) {
244
293
  splaytree *tree = ptr;
245
294
  recursively_free_nodes(tree->root);
246
- free(tree->header);
247
- free(tree);
295
+ xfree(tree);
248
296
  }
249
297
  }
250
298
 
@@ -255,7 +303,7 @@ static VALUE splaytree_alloc(VALUE klass) {
255
303
 
256
304
  static VALUE splaytree_push(VALUE self, VALUE key, VALUE value) {
257
305
  splaytree *tree = get_tree_from_self(self);
258
- insert(tree, key, value);
306
+ tree->root = insert(tree, tree->root, key, value);
259
307
  return value;
260
308
  }
261
309
 
@@ -266,7 +314,8 @@ static VALUE splaytree_get(VALUE self, VALUE key) {
266
314
 
267
315
  static VALUE splaytree_size(VALUE self) {
268
316
  splaytree *tree = get_tree_from_self(self);
269
- return INT2NUM(tree->size);
317
+ if(!tree->root) { return INT2NUM(0); }
318
+ return INT2NUM(tree->root->size);
270
319
  }
271
320
 
272
321
  static VALUE splaytree_is_empty(VALUE self) {
@@ -317,19 +366,19 @@ static VALUE splaytree_max_key(VALUE self) {
317
366
  }
318
367
 
319
368
  static VALUE splaytree_delete(VALUE self, VALUE key) {
369
+ VALUE deleted = Qnil;
320
370
  splaytree *tree = get_tree_from_self(self);
321
371
  if(!tree->root)
322
372
  return Qnil;
323
373
 
324
- return delete(tree, key);
374
+ tree->root = delete(tree, tree->root, key, &deleted);
375
+ return deleted;
325
376
  }
326
377
 
327
378
  static VALUE splaytree_clear(VALUE self) {
328
379
  splaytree *tree = get_tree_from_self(self);
329
380
  recursively_free_nodes(tree->root);
330
381
  tree->root = NULL;
331
- tree->size = 0;
332
-
333
382
  return Qnil;
334
383
  }
335
384