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,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 LoadError # C Version could not be found, try ruby version
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