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,402 +1,402 @@
1
- require 'containers/stack'
2
- =begin rdoc
3
- A RBTreeMap is a map that is stored in sorted order based on the order of its keys. This ordering is
4
- determined by applying the function <=> to compare the keys. No duplicate values for keys are allowed,
5
- so duplicate values are overwritten.
6
-
7
- A major advantage of RBTreeMap over a Hash is the fact that keys are stored in order and can thus be
8
- iterated over in order. This is useful for many datasets.
9
-
10
- The implementation is adapted from Robert Sedgewick's Left Leaning Red-Black Tree implementation,
11
- which can be found at http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
12
-
13
- Algorithms::Containers::RBTreeMap automatically uses the faster C implementation if it was built
14
- when the gem was installed. Alternatively, Algorithms::Containers::RubyRBTreeMap and Algorithms::Containers::CRBTreeMap can be
15
- explicitly used as well; their functionality is identical.
16
-
17
- Most methods have O(log n) complexity.
18
-
19
- =end
20
- module Algorithms
21
- module Containers
22
- class RubyRBTreeMap
23
- include Enumerable
24
-
25
- attr_accessor :height_black
26
-
27
- # Create and initialize a new empty TreeMap.
28
- def initialize
29
- @root = nil
30
- @height_black = 0
31
- end
32
-
33
- # Insert an item with an associated key into the TreeMap, and returns the item inserted
34
- #
35
- # Complexity: O(log n)
36
- #
37
- # map = Algorithms::Containers::TreeMap.new
38
- # map.push("MA", "Massachusetts") #=> "Massachusetts"
39
- # map.get("MA") #=> "Massachusetts"
40
- def push(key, value)
41
- @root = insert(@root, key, value)
42
- @height_black += 1 if isred(@root)
43
- @root.color = :black
44
- value
45
- end
46
- alias_method :[]=, :push
47
-
48
- # Return the number of items in the TreeMap.
49
- #
50
- # map = Algorithms::Containers::TreeMap.new
51
- # map.push("MA", "Massachusetts")
52
- # map.push("GA", "Georgia")
53
- # map.size #=> 2
54
- def size
55
- @root and @root.size or 0
56
- end
57
-
58
- # Return the height of the tree structure in the TreeMap.
59
- #
60
- # Complexity: O(1)
61
- #
62
- # map = Algorithms::Containers::TreeMap.new
63
- # map.push("MA", "Massachusetts")
64
- # map.push("GA", "Georgia")
65
- # map.height #=> 2
66
- def height
67
- @root and @root.height or 0
68
- end
69
-
70
- # Return true if key is found in the TreeMap, false otherwise
71
- #
72
- # Complexity: O(log n)
73
- #
74
- # map = Algorithms::Containers::TreeMap.new
75
- # map.push("MA", "Massachusetts")
76
- # map.push("GA", "Georgia")
77
- # map.has_key?("GA") #=> true
78
- # map.has_key?("DE") #=> false
79
- def has_key?(key)
80
- !get(key).nil?
81
- end
82
-
83
- # Return the item associated with the key, or nil if none found.
84
- #
85
- # Complexity: O(log n)
86
- #
87
- # map = Algorithms::Containers::TreeMap.new
88
- # map.push("MA", "Massachusetts")
89
- # map.push("GA", "Georgia")
90
- # map.get("GA") #=> "Georgia"
91
- def get(key)
92
- get_recursive(@root, key)
93
- end
94
- alias_method :[], :get
95
-
96
- # Return the smallest key in the map.
97
- #
98
- # Complexity: O(log n)
99
- #
100
- # map = Algorithms::Containers::TreeMap.new
101
- # map.push("MA", "Massachusetts")
102
- # map.push("GA", "Georgia")
103
- # map.min_key #=> "GA"
104
- def min_key
105
- @root.nil? ? nil : min_recursive(@root)
106
- end
107
-
108
- # Return the largest key in the map.
109
- #
110
- # Complexity: O(log n)
111
- #
112
- # map = Algorithms::Containers::TreeMap.new
113
- # map.push("MA", "Massachusetts")
114
- # map.push("GA", "Georgia")
115
- # map.max_key #=> "MA"
116
- def max_key
117
- @root.nil? ? nil : max_recursive(@root)
118
- end
119
-
120
- # Deletes the item and key if it's found, and returns the item. Returns nil
121
- # if key is not present.
122
- #
123
- # !!! Warning !!! There is a currently a bug in the delete method that occurs rarely
124
- # but often enough, especially in large datasets. It is currently under investigation.
125
- #
126
- # Complexity: O(log n)
127
- #
128
- # map = Algorithms::Containers::TreeMap.new
129
- # map.push("MA", "Massachusetts")
130
- # map.push("GA", "Georgia")
131
- # map.min_key #=> "GA"
132
- def delete(key)
133
- result = nil
134
- if @root
135
- @root, result = delete_recursive(@root, key)
136
- @root.color = :black if @root
137
- end
138
- result
139
- end
140
-
141
- # Returns true if the tree is empty, false otherwise
142
- def empty?
143
- @root.nil?
144
- end
145
-
146
- # Deletes the item with the smallest key and returns the item. Returns nil
147
- # if key is not present.
148
- #
149
- # Complexity: O(log n)
150
- #
151
- # map = Algorithms::Containers::TreeMap.new
152
- # map.push("MA", "Massachusetts")
153
- # map.push("GA", "Georgia")
154
- # map.delete_min #=> "Massachusetts"
155
- # map.size #=> 1
156
- def delete_min
157
- result = nil
158
- if @root
159
- @root, result = delete_min_recursive(@root)
160
- @root.color = :black if @root
161
- end
162
- result
163
- end
164
-
165
- # Deletes the item with the smallest key and returns the item. Returns nil
166
- # if key is not present.
167
- #
168
- # Complexity: O(log n)
169
- #
170
- # map = Algorithms::Containers::TreeMap.new
171
- # map.push("MA", "Massachusetts")
172
- # map.push("GA", "Georgia")
173
- # map.delete_max #=> "Georgia"
174
- # map.size #=> 1
175
- def delete_max
176
- result = nil
177
- if @root
178
- @root, result = delete_max_recursive(@root)
179
- @root.color = :black if @root
180
- end
181
- result
182
- end
183
-
184
- # Iterates over the TreeMap from smallest to largest element. Iterative approach.
185
- def each
186
- return nil unless @root
187
- stack = Stack.new
188
- cursor = @root
189
- loop do
190
- if cursor
191
- stack.push(cursor)
192
- cursor = cursor.left
193
- else
194
- unless stack.empty?
195
- cursor = stack.pop
196
- yield(cursor.key, cursor.value)
197
- cursor = cursor.right
198
- else
199
- break
200
- end
201
- end
202
- end
203
- end
204
-
205
- class Node # :nodoc: all
206
- attr_accessor :color, :key, :value, :left, :right, :size, :height
207
- def initialize(key, value)
208
- @key = key
209
- @value = value
210
- @color = :red
211
- @left = nil
212
- @right = nil
213
- @size = 1
214
- @height = 1
215
- end
216
-
217
- def red?
218
- @color == :red
219
- end
220
-
221
- def colorflip
222
- @color = @color == :red ? :black : :red
223
- @left.color = @left.color == :red ? :black : :red
224
- @right.color = @right.color == :red ? :black : :red
225
- end
226
-
227
- def update_size
228
- @size = (@left ? @left.size : 0) + (@right ? @right.size : 0) + 1
229
- left_height = (@left ? @left.height : 0)
230
- right_height = (@right ? @right.height : 0)
231
- if left_height > right_height
232
- @height = left_height + 1
233
- else
234
- @height = right_height + 1
235
- end
236
- self
237
- end
238
-
239
- def rotate_left
240
- r = @right
241
- r_key, r_value, r_color = r.key, r.value, r.color
242
- b = r.left
243
- r.left = @left
244
- @left = r
245
- @right = r.right
246
- r.right = b
247
- r.color, r.key, r.value = :red, @key, @value
248
- @key, @value = r_key, r_value
249
- r.update_size
250
- update_size
251
- end
252
-
253
- def rotate_right
254
- l = @left
255
- l_key, l_value, l_color = l.key, l.value, l.color
256
- b = l.right
257
- l.right = @right
258
- @right = l
259
- @left = l.left
260
- l.left = b
261
- l.color, l.key, l.value = :red, @key, @value
262
- @key, @value = l_key, l_value
263
- l.update_size
264
- update_size
265
- end
266
-
267
- def move_red_left
268
- colorflip
269
- if (@right.left && @right.left.red?)
270
- @right.rotate_right
271
- rotate_left
272
- colorflip
273
- end
274
- self
275
- end
276
-
277
- def move_red_right
278
- colorflip
279
- if (@left.left && @left.left.red?)
280
- rotate_right
281
- colorflip
282
- end
283
- self
284
- end
285
-
286
- def fixup
287
- rotate_left if @right && @right.red?
288
- rotate_right if (@left && @left.red?) && (@left.left && @left.left.red?)
289
- colorflip if (@left && @left.red?) && (@right && @right.red?)
290
-
291
- update_size
292
- end
293
- end
294
-
295
- def delete_recursive(node, key)
296
- if (key <=> node.key) == -1
297
- node.move_red_left if ( !isred(node.left) && !isred(node.left.left) )
298
- node.left, result = delete_recursive(node.left, key)
299
- else
300
- node.rotate_right if isred(node.left)
301
- if ( ( (key <=> node.key) == 0) && node.right.nil? )
302
- return nil, node.value
303
- end
304
- if ( !isred(node.right) && !isred(node.right.left) )
305
- node.move_red_right
306
- end
307
- if (key <=> node.key) == 0
308
- result = node.value
309
- node.value = get_recursive(node.right, min_recursive(node.right))
310
- node.key = min_recursive(node.right)
311
- node.right = delete_min_recursive(node.right).first
312
- else
313
- node.right, result = delete_recursive(node.right, key)
314
- end
315
- end
316
- return node.fixup, result
317
- end
318
- private :delete_recursive
319
-
320
- def delete_min_recursive(node)
321
- if node.left.nil?
322
- return nil, node.value
323
- end
324
- if ( !isred(node.left) && !isred(node.left.left) )
325
- node.move_red_left
326
- end
327
- node.left, result = delete_min_recursive(node.left)
328
-
329
- return node.fixup, result
330
- end
331
- private :delete_min_recursive
332
-
333
- def delete_max_recursive(node)
334
- if (isred(node.left))
335
- node = node.rotate_right
336
- end
337
- return nil, node.value if node.right.nil?
338
- if ( !isred(node.right) && !isred(node.right.left) )
339
- node.move_red_right
340
- end
341
- node.right, result = delete_max_recursive(node.right)
342
-
343
- return node.fixup, result
344
- end
345
- private :delete_max_recursive
346
-
347
- def get_recursive(node, key)
348
- return nil if node.nil?
349
- case key <=> node.key
350
- when 0 then return node.value
351
- when -1 then return get_recursive(node.left, key)
352
- when 1 then return get_recursive(node.right, key)
353
- end
354
- end
355
- private :get_recursive
356
-
357
- def min_recursive(node)
358
- return node.key if node.left.nil?
359
-
360
- min_recursive(node.left)
361
- end
362
- private :min_recursive
363
-
364
- def max_recursive(node)
365
- return node.key if node.right.nil?
366
-
367
- max_recursive(node.right)
368
- end
369
- private :max_recursive
370
-
371
- def insert(node, key, value)
372
- return Node.new(key, value) unless node
373
-
374
- case key <=> node.key
375
- when 0 then node.value = value
376
- when -1 then node.left = insert(node.left, key, value)
377
- when 1 then node.right = insert(node.right, key, value)
378
- end
379
-
380
- node.rotate_left if (node.right && node.right.red?)
381
- node.rotate_right if (node.left && node.left.red? && node.left.left && node.left.left.red?)
382
- node.colorflip if (node.left && node.left.red? && node.right && node.right.red?)
383
- node.update_size
384
- end
385
- private :insert
386
-
387
- def isred(node)
388
- return false if node.nil?
389
-
390
- node.color == :red
391
- end
392
- private :isred
393
- end
394
- end
395
-
396
- begin
397
- require 'CRBTreeMap'
398
- Containers::RBTreeMap = Containers::CRBTreeMap
399
- rescue LoadError # C Version could not be found, try ruby version
400
- Containers::RBTreeMap = Containers::RubyRBTreeMap
401
- end
402
- end
1
+ require 'containers/stack'
2
+ =begin rdoc
3
+ A RBTreeMap is a map that is stored in sorted order based on the order of its keys. This ordering is
4
+ determined by applying the function <=> to compare the keys. No duplicate values for keys are allowed,
5
+ so duplicate values are overwritten.
6
+
7
+ A major advantage of RBTreeMap over a Hash is the fact that keys are stored in order and can thus be
8
+ iterated over in order. This is useful for many datasets.
9
+
10
+ The implementation is adapted from Robert Sedgewick's Left Leaning Red-Black Tree implementation,
11
+ which can be found at http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
12
+
13
+ Algorithms::Containers::RBTreeMap automatically uses the faster C implementation if it was built
14
+ when the gem was installed. Alternatively, Algorithms::Containers::RubyRBTreeMap and Algorithms::Containers::CRBTreeMap can be
15
+ explicitly used as well; their functionality is identical.
16
+
17
+ Most methods have O(log n) complexity.
18
+
19
+ =end
20
+ module Algorithms
21
+ module Containers
22
+ class RubyRBTreeMap
23
+ include Enumerable
24
+
25
+ attr_accessor :height_black
26
+
27
+ # Create and initialize a new empty TreeMap.
28
+ def initialize
29
+ @root = nil
30
+ @height_black = 0
31
+ end
32
+
33
+ # Insert an item with an associated key into the TreeMap, and returns the item inserted
34
+ #
35
+ # Complexity: O(log n)
36
+ #
37
+ # map = Algorithms::Containers::TreeMap.new
38
+ # map.push("MA", "Massachusetts") #=> "Massachusetts"
39
+ # map.get("MA") #=> "Massachusetts"
40
+ def push(key, value)
41
+ @root = insert(@root, key, value)
42
+ @height_black += 1 if isred(@root)
43
+ @root.color = :black
44
+ value
45
+ end
46
+ alias_method :[]=, :push
47
+
48
+ # Return the number of items in the TreeMap.
49
+ #
50
+ # map = Algorithms::Containers::TreeMap.new
51
+ # map.push("MA", "Massachusetts")
52
+ # map.push("GA", "Georgia")
53
+ # map.size #=> 2
54
+ def size
55
+ @root and @root.size or 0
56
+ end
57
+
58
+ # Return the height of the tree structure in the TreeMap.
59
+ #
60
+ # Complexity: O(1)
61
+ #
62
+ # map = Algorithms::Containers::TreeMap.new
63
+ # map.push("MA", "Massachusetts")
64
+ # map.push("GA", "Georgia")
65
+ # map.height #=> 2
66
+ def height
67
+ @root and @root.height or 0
68
+ end
69
+
70
+ # Return true if key is found in the TreeMap, false otherwise
71
+ #
72
+ # Complexity: O(log n)
73
+ #
74
+ # map = Algorithms::Containers::TreeMap.new
75
+ # map.push("MA", "Massachusetts")
76
+ # map.push("GA", "Georgia")
77
+ # map.has_key?("GA") #=> true
78
+ # map.has_key?("DE") #=> false
79
+ def has_key?(key)
80
+ !get(key).nil?
81
+ end
82
+
83
+ # Return the item associated with the key, or nil if none found.
84
+ #
85
+ # Complexity: O(log n)
86
+ #
87
+ # map = Algorithms::Containers::TreeMap.new
88
+ # map.push("MA", "Massachusetts")
89
+ # map.push("GA", "Georgia")
90
+ # map.get("GA") #=> "Georgia"
91
+ def get(key)
92
+ get_recursive(@root, key)
93
+ end
94
+ alias_method :[], :get
95
+
96
+ # Return the smallest key in the map.
97
+ #
98
+ # Complexity: O(log n)
99
+ #
100
+ # map = Algorithms::Containers::TreeMap.new
101
+ # map.push("MA", "Massachusetts")
102
+ # map.push("GA", "Georgia")
103
+ # map.min_key #=> "GA"
104
+ def min_key
105
+ @root.nil? ? nil : min_recursive(@root)
106
+ end
107
+
108
+ # Return the largest key in the map.
109
+ #
110
+ # Complexity: O(log n)
111
+ #
112
+ # map = Algorithms::Containers::TreeMap.new
113
+ # map.push("MA", "Massachusetts")
114
+ # map.push("GA", "Georgia")
115
+ # map.max_key #=> "MA"
116
+ def max_key
117
+ @root.nil? ? nil : max_recursive(@root)
118
+ end
119
+
120
+ # Deletes the item and key if it's found, and returns the item. Returns nil
121
+ # if key is not present.
122
+ #
123
+ # !!! Warning !!! There is a currently a bug in the delete method that occurs rarely
124
+ # but often enough, especially in large datasets. It is currently under investigation.
125
+ #
126
+ # Complexity: O(log n)
127
+ #
128
+ # map = Algorithms::Containers::TreeMap.new
129
+ # map.push("MA", "Massachusetts")
130
+ # map.push("GA", "Georgia")
131
+ # map.min_key #=> "GA"
132
+ def delete(key)
133
+ result = nil
134
+ if @root
135
+ @root, result = delete_recursive(@root, key)
136
+ @root.color = :black if @root
137
+ end
138
+ result
139
+ end
140
+
141
+ # Returns true if the tree is empty, false otherwise
142
+ def empty?
143
+ @root.nil?
144
+ end
145
+
146
+ # Deletes the item with the smallest key and returns the item. Returns nil
147
+ # if key is not present.
148
+ #
149
+ # Complexity: O(log n)
150
+ #
151
+ # map = Algorithms::Containers::TreeMap.new
152
+ # map.push("MA", "Massachusetts")
153
+ # map.push("GA", "Georgia")
154
+ # map.delete_min #=> "Massachusetts"
155
+ # map.size #=> 1
156
+ def delete_min
157
+ result = nil
158
+ if @root
159
+ @root, result = delete_min_recursive(@root)
160
+ @root.color = :black if @root
161
+ end
162
+ result
163
+ end
164
+
165
+ # Deletes the item with the smallest key and returns the item. Returns nil
166
+ # if key is not present.
167
+ #
168
+ # Complexity: O(log n)
169
+ #
170
+ # map = Algorithms::Containers::TreeMap.new
171
+ # map.push("MA", "Massachusetts")
172
+ # map.push("GA", "Georgia")
173
+ # map.delete_max #=> "Georgia"
174
+ # map.size #=> 1
175
+ def delete_max
176
+ result = nil
177
+ if @root
178
+ @root, result = delete_max_recursive(@root)
179
+ @root.color = :black if @root
180
+ end
181
+ result
182
+ end
183
+
184
+ # Iterates over the TreeMap from smallest to largest element. Iterative approach.
185
+ def each
186
+ return nil unless @root
187
+ stack = Stack.new
188
+ cursor = @root
189
+ loop do
190
+ if cursor
191
+ stack.push(cursor)
192
+ cursor = cursor.left
193
+ else
194
+ unless stack.empty?
195
+ cursor = stack.pop
196
+ yield(cursor.key, cursor.value)
197
+ cursor = cursor.right
198
+ else
199
+ break
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ class Node # :nodoc: all
206
+ attr_accessor :color, :key, :value, :left, :right, :size, :height
207
+ def initialize(key, value)
208
+ @key = key
209
+ @value = value
210
+ @color = :red
211
+ @left = nil
212
+ @right = nil
213
+ @size = 1
214
+ @height = 1
215
+ end
216
+
217
+ def red?
218
+ @color == :red
219
+ end
220
+
221
+ def colorflip
222
+ @color = @color == :red ? :black : :red
223
+ @left.color = @left.color == :red ? :black : :red
224
+ @right.color = @right.color == :red ? :black : :red
225
+ end
226
+
227
+ def update_size
228
+ @size = (@left ? @left.size : 0) + (@right ? @right.size : 0) + 1
229
+ left_height = (@left ? @left.height : 0)
230
+ right_height = (@right ? @right.height : 0)
231
+ if left_height > right_height
232
+ @height = left_height + 1
233
+ else
234
+ @height = right_height + 1
235
+ end
236
+ self
237
+ end
238
+
239
+ def rotate_left
240
+ r = @right
241
+ r_key, r_value, r_color = r.key, r.value, r.color
242
+ b = r.left
243
+ r.left = @left
244
+ @left = r
245
+ @right = r.right
246
+ r.right = b
247
+ r.color, r.key, r.value = :red, @key, @value
248
+ @key, @value = r_key, r_value
249
+ r.update_size
250
+ update_size
251
+ end
252
+
253
+ def rotate_right
254
+ l = @left
255
+ l_key, l_value, l_color = l.key, l.value, l.color
256
+ b = l.right
257
+ l.right = @right
258
+ @right = l
259
+ @left = l.left
260
+ l.left = b
261
+ l.color, l.key, l.value = :red, @key, @value
262
+ @key, @value = l_key, l_value
263
+ l.update_size
264
+ update_size
265
+ end
266
+
267
+ def move_red_left
268
+ colorflip
269
+ if (@right.left && @right.left.red?)
270
+ @right.rotate_right
271
+ rotate_left
272
+ colorflip
273
+ end
274
+ self
275
+ end
276
+
277
+ def move_red_right
278
+ colorflip
279
+ if (@left.left && @left.left.red?)
280
+ rotate_right
281
+ colorflip
282
+ end
283
+ self
284
+ end
285
+
286
+ def fixup
287
+ rotate_left if @right && @right.red?
288
+ rotate_right if (@left && @left.red?) && (@left.left && @left.left.red?)
289
+ colorflip if (@left && @left.red?) && (@right && @right.red?)
290
+
291
+ update_size
292
+ end
293
+ end
294
+
295
+ def delete_recursive(node, key)
296
+ if (key <=> node.key) == -1
297
+ node.move_red_left if ( !isred(node.left) && !isred(node.left.left) )
298
+ node.left, result = delete_recursive(node.left, key)
299
+ else
300
+ node.rotate_right if isred(node.left)
301
+ if ( ( (key <=> node.key) == 0) && node.right.nil? )
302
+ return nil, node.value
303
+ end
304
+ if ( !isred(node.right) && !isred(node.right.left) )
305
+ node.move_red_right
306
+ end
307
+ if (key <=> node.key) == 0
308
+ result = node.value
309
+ node.value = get_recursive(node.right, min_recursive(node.right))
310
+ node.key = min_recursive(node.right)
311
+ node.right = delete_min_recursive(node.right).first
312
+ else
313
+ node.right, result = delete_recursive(node.right, key)
314
+ end
315
+ end
316
+ return node.fixup, result
317
+ end
318
+ private :delete_recursive
319
+
320
+ def delete_min_recursive(node)
321
+ if node.left.nil?
322
+ return nil, node.value
323
+ end
324
+ if ( !isred(node.left) && !isred(node.left.left) )
325
+ node.move_red_left
326
+ end
327
+ node.left, result = delete_min_recursive(node.left)
328
+
329
+ return node.fixup, result
330
+ end
331
+ private :delete_min_recursive
332
+
333
+ def delete_max_recursive(node)
334
+ if (isred(node.left))
335
+ node = node.rotate_right
336
+ end
337
+ return nil, node.value if node.right.nil?
338
+ if ( !isred(node.right) && !isred(node.right.left) )
339
+ node.move_red_right
340
+ end
341
+ node.right, result = delete_max_recursive(node.right)
342
+
343
+ return node.fixup, result
344
+ end
345
+ private :delete_max_recursive
346
+
347
+ def get_recursive(node, key)
348
+ return nil if node.nil?
349
+ case key <=> node.key
350
+ when 0 then return node.value
351
+ when -1 then return get_recursive(node.left, key)
352
+ when 1 then return get_recursive(node.right, key)
353
+ end
354
+ end
355
+ private :get_recursive
356
+
357
+ def min_recursive(node)
358
+ return node.key if node.left.nil?
359
+
360
+ min_recursive(node.left)
361
+ end
362
+ private :min_recursive
363
+
364
+ def max_recursive(node)
365
+ return node.key if node.right.nil?
366
+
367
+ max_recursive(node.right)
368
+ end
369
+ private :max_recursive
370
+
371
+ def insert(node, key, value)
372
+ return Node.new(key, value) unless node
373
+
374
+ case key <=> node.key
375
+ when 0 then node.value = value
376
+ when -1 then node.left = insert(node.left, key, value)
377
+ when 1 then node.right = insert(node.right, key, value)
378
+ end
379
+
380
+ node.rotate_left if (node.right && node.right.red?)
381
+ node.rotate_right if (node.left && node.left.red? && node.left.left && node.left.left.red?)
382
+ node.colorflip if (node.left && node.left.red? && node.right && node.right.red?)
383
+ node.update_size
384
+ end
385
+ private :insert
386
+
387
+ def isred(node)
388
+ return false if node.nil?
389
+
390
+ node.color == :red
391
+ end
392
+ private :isred
393
+ end
394
+ end
395
+
396
+ begin
397
+ require 'CRBTreeMap'
398
+ Containers::RBTreeMap = Containers::CRBTreeMap
399
+ rescue # C Version could not be found, try ruby version
400
+ Containers::RBTreeMap = Containers::RubyRBTreeMap
401
+ end
402
+ end