algorithm_selector 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/.yardoc/checksums +2 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +45 -0
- data/Rakefile +6 -0
- data/algorithm_selector.gemspec +35 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/AlgorithmSelector.html +505 -0
- data/doc/BSTNode.html +440 -0
- data/doc/BinaryTree.html +572 -0
- data/doc/LinkNode.html +440 -0
- data/doc/LinkedList.html +879 -0
- data/doc/Queue.html +569 -0
- data/doc/Searches.html +442 -0
- data/doc/Sorts.html +916 -0
- data/doc/Stack.html +723 -0
- data/doc/_index.html +183 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +481 -0
- data/doc/file.README.html +129 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +129 -0
- data/doc/js/app.js +243 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +507 -0
- data/doc/top-level-namespace.html +114 -0
- data/lib/.DS_Store +0 -0
- data/lib/algorithm_selector.rb +562 -0
- data/lib/algorithm_selector/version.rb +3 -0
- metadata +129 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.4
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
pathId = "";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
|
41
|
+
|
42
|
+
<span class="title">Top Level Namespace</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<iframe id="search_frame" src="class_list.html"></iframe>
|
63
|
+
|
64
|
+
<div id="content"><h1>Top Level Namespace
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
</h1>
|
69
|
+
<div class="box_info">
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
</div>
|
82
|
+
|
83
|
+
<h2>Defined Under Namespace</h2>
|
84
|
+
<p class="children">
|
85
|
+
|
86
|
+
|
87
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="AlgorithmSelector.html" title="AlgorithmSelector (module)">AlgorithmSelector</a></span>
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
<strong class="classes">Classes:</strong> <span class='object_link'><a href="BSTNode.html" title="BSTNode (class)">BSTNode</a></span>, <span class='object_link'><a href="BinaryTree.html" title="BinaryTree (class)">BinaryTree</a></span>, <span class='object_link'><a href="LinkNode.html" title="LinkNode (class)">LinkNode</a></span>, <span class='object_link'><a href="LinkedList.html" title="LinkedList (class)">LinkedList</a></span>, <span class='object_link'><a href="Queue.html" title="Queue (class)">Queue</a></span>, <span class='object_link'><a href="Searches.html" title="Searches (class)">Searches</a></span>, <span class='object_link'><a href="Sorts.html" title="Sorts (class)">Sorts</a></span>, <span class='object_link'><a href="Stack.html" title="Stack (class)">Stack</a></span>
|
92
|
+
|
93
|
+
|
94
|
+
</p>
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
</div>
|
105
|
+
|
106
|
+
<div id="footer">
|
107
|
+
Generated on Fri Jul 22 11:22:30 2016 by
|
108
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
109
|
+
0.9.4 (ruby-2.1.2).
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</div>
|
113
|
+
</body>
|
114
|
+
</html>
|
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,562 @@
|
|
1
|
+
require "algorithm_selector/version"
|
2
|
+
|
3
|
+
module AlgorithmSelector
|
4
|
+
extend self
|
5
|
+
|
6
|
+
# get all algorithms
|
7
|
+
def all(type, array, num_tests=1, target=nil)
|
8
|
+
if type == "sort"
|
9
|
+
Sorts.new.all(array, num_tests)
|
10
|
+
elsif type == "search"
|
11
|
+
Searches.new.all(array, num_tests, target)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# get best algorithm
|
16
|
+
def best(type, array, num_tests=1, target=nil)
|
17
|
+
if type == "sort"
|
18
|
+
Sorts.new.best(array, num_tests)
|
19
|
+
elsif type == "search"
|
20
|
+
Searches.new.best(array, num_tests, target)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# get one algorithm by name
|
25
|
+
def analyze(type, array, algorithm_name, num_tests=1, target=nil)
|
26
|
+
if type == "sort"
|
27
|
+
Sorts.new.analyze(array, algorithm_name, num_tests)
|
28
|
+
elsif type == "search"
|
29
|
+
Searches.new.analyze(array, algorithm_name, num_tests, target)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# compare two algorithms
|
34
|
+
def compare(type, array, first_algorithm_name, second_algorithm_name, num_tests=1, target=nil)
|
35
|
+
if type == "sort"
|
36
|
+
Sorts.new.compare(array, first_algorithm_name, second_algorithm_name, num_tests)
|
37
|
+
elsif type == "search"
|
38
|
+
Searches.new.compare(array, first_algorithm_name, second_algorithm_name, num_tests, target)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# call sort algorithm method
|
43
|
+
def sort(array, algorithm_name)
|
44
|
+
method = Sorts.new.method(algorithm_name)
|
45
|
+
method.call(array)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sorts class
|
51
|
+
class Sorts
|
52
|
+
# Show all results from sorting algorithms
|
53
|
+
def all(array, num_tests)
|
54
|
+
{
|
55
|
+
sorted: merge_sort(array),
|
56
|
+
results: {
|
57
|
+
bubble_sort: display_time(Proc.new {bubble_sort(array)}, num_tests),
|
58
|
+
insertion_sort: display_time(Proc.new {insertion_sort(array)}, num_tests),
|
59
|
+
selection_sort: display_time(Proc.new {selection_sort(array)}, num_tests),
|
60
|
+
merge_sort: display_time(Proc.new {merge_sort(array)}, num_tests),
|
61
|
+
quick_sort: display_time(Proc.new {quick_sort(array)}, num_tests)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
# Show the best sorting algorithm
|
67
|
+
def best(array, num_tests)
|
68
|
+
hash = all(array, num_tests)
|
69
|
+
best_time = 0
|
70
|
+
best_algorithm = {}
|
71
|
+
hash[:results].each do |key, val|
|
72
|
+
if val < best_time || best_time == 0
|
73
|
+
best_time = val
|
74
|
+
best_algorithm = Hash[key, val]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
{
|
78
|
+
best_algorithm.keys[0] => best_algorithm[best_algorithm.keys[0]]
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
# Analyze specific sorting algorithm by name
|
83
|
+
def analyze(array, algorithm, num_tests)
|
84
|
+
hash = all(array, num_tests)
|
85
|
+
alg = {}
|
86
|
+
hash[:results].each do |key, val|
|
87
|
+
if algorithm.to_sym == key
|
88
|
+
alg = Hash[key, val]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
{
|
92
|
+
sorted: hash[:sorted],
|
93
|
+
alg.keys[0] => alg[alg.keys[0]]
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
# Compare two algorithms for data set
|
98
|
+
def compare(array, first_algorithm, second_algorithm, num_tests)
|
99
|
+
hash = all(array, num_tests)
|
100
|
+
first = {}
|
101
|
+
second = {}
|
102
|
+
hash[:results].each do |key, val|
|
103
|
+
if first_algorithm.to_sym == key
|
104
|
+
first = Hash[key, val]
|
105
|
+
elsif second_algorithm.to_sym == key
|
106
|
+
second = Hash[key, val]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
{
|
110
|
+
first.keys[0] => first[first.keys[0]],
|
111
|
+
second.keys[0] => second[second.keys[0]]
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
# Bubble sort
|
116
|
+
# Worst-Case Space Complexity: O(1)
|
117
|
+
# Averge-Case Time Complexity: O(n^2)
|
118
|
+
# Worst-Case Time Complexity: O(n^2)
|
119
|
+
def bubble_sort(array)
|
120
|
+
return array if array.length < 2
|
121
|
+
switched = true
|
122
|
+
until switched == false
|
123
|
+
switched = false
|
124
|
+
(1...array.length).each do |i|
|
125
|
+
if array[i-1] > array[i]
|
126
|
+
temp = array[i]
|
127
|
+
array[i] = array[i-1]
|
128
|
+
array[i-1] = temp
|
129
|
+
switched = true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
return array
|
134
|
+
end
|
135
|
+
|
136
|
+
# Insertion sort
|
137
|
+
# Worst-Case Space Complexity: O(1)
|
138
|
+
# Averge-Case Time Complexity: O(n^2)
|
139
|
+
# Worst-Case Time Complexity: O(n^2)
|
140
|
+
def insertion_sort(array)
|
141
|
+
return array if array.length < 2
|
142
|
+
(1...array.length).to_a do |i|
|
143
|
+
value = array[i]
|
144
|
+
j = i - 1
|
145
|
+
while (j >= 0 && array[j] > value) do
|
146
|
+
array[j+1] = array[j]
|
147
|
+
j = j - 1
|
148
|
+
end
|
149
|
+
array[j+1] = value
|
150
|
+
end
|
151
|
+
array
|
152
|
+
end
|
153
|
+
|
154
|
+
# Selection sort
|
155
|
+
# Worst-Case Space Complexity: O(1)
|
156
|
+
# Averge-Case Time Complexity: O(n^2)
|
157
|
+
# Worst-Case Time Complexity: O(n^2)
|
158
|
+
def selection_sort(array)
|
159
|
+
(0...array.length-1).to_a.each do |i|
|
160
|
+
min = i
|
161
|
+
(i+1...array.length).to_a.each do |j|
|
162
|
+
if (array[j] < array[min])
|
163
|
+
min = j
|
164
|
+
end
|
165
|
+
end
|
166
|
+
if min != i
|
167
|
+
array[min], array[i] = array[i], array[min]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
return array
|
171
|
+
end
|
172
|
+
|
173
|
+
# Merge sort
|
174
|
+
# Worst-Case Space Complexity: O(n)
|
175
|
+
# Averge-Case Time Complexity: O(n log(n))
|
176
|
+
# Worst-Case Time Complexity: O(n log(n))
|
177
|
+
def merge_sort(array)
|
178
|
+
return array if array.length < 2
|
179
|
+
middle = array.length/2
|
180
|
+
left = array[0...middle]
|
181
|
+
right = array[middle...array.length]
|
182
|
+
merge(merge_sort(left), merge_sort(right))
|
183
|
+
end
|
184
|
+
|
185
|
+
# Quick sort
|
186
|
+
# Worst-Case Space Complexity: O(log(n))
|
187
|
+
# Averge-Case Time Complexity: O(n log(n))
|
188
|
+
# Worst-Case Time Complexity: O(n^2)
|
189
|
+
def quick_sort(array)
|
190
|
+
return array if array.count < 2
|
191
|
+
pivot = array[0]
|
192
|
+
left = array.select {|el| el < pivot}
|
193
|
+
right = array.select {|el| el > pivot}
|
194
|
+
quick_sort(left) + [pivot] + quick_sort(right)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class Searches
|
199
|
+
def all(array, num_tests, target)
|
200
|
+
stack = Stack.new(array.length, array)
|
201
|
+
queue = Queue.new(array.length, array)
|
202
|
+
linked_list = LinkedList.new(array)
|
203
|
+
binary_tree = BinaryTree.new(array)
|
204
|
+
{
|
205
|
+
found: stack.search(target),
|
206
|
+
results:
|
207
|
+
{
|
208
|
+
stack: display_time(Proc.new {stack.search(target)}, num_tests),
|
209
|
+
queue: display_time(Proc.new {queue.search(target)}, num_tests),
|
210
|
+
linked_list: display_time(Proc.new {linked_list.search(target)}, num_tests),
|
211
|
+
binary_tree: display_time(Proc.new {binary_tree.search(target)}, num_tests)
|
212
|
+
}
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
def best(array, num_tests, target)
|
217
|
+
hash = all(array, num_tests, target)
|
218
|
+
best_time = 0
|
219
|
+
best_algorithm = {}
|
220
|
+
hash[:results].each do |key, val|
|
221
|
+
if val < best_time || best_time == 0
|
222
|
+
best_time = val
|
223
|
+
best_algorithm = Hash[key, val]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
{
|
227
|
+
best_algorithm.keys[0] => best_algorithm[best_algorithm.keys[0]]
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
def analyze(array, algorithm, num_tests, target)
|
232
|
+
hash = all(array, num_tests, target)
|
233
|
+
alg = {}
|
234
|
+
hash[:results].each do |key, val|
|
235
|
+
if algorithm.to_sym == key
|
236
|
+
alg = Hash[key, val]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
{
|
240
|
+
found: hash[:found],
|
241
|
+
alg.keys[0] => alg[alg.keys[0]]
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
def compare(array, first_algorithm, second_algorithm, num_tests, target)
|
246
|
+
hash = all(array, num_tests, target)
|
247
|
+
first = {}
|
248
|
+
second = {}
|
249
|
+
hash[:results].each do |key, val|
|
250
|
+
if first_algorithm.to_sym == key
|
251
|
+
first = Hash[key, val]
|
252
|
+
elsif second_algorithm.to_sym == key
|
253
|
+
second = Hash[key, val]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
{
|
257
|
+
first.keys[0] => first[first.keys[0]],
|
258
|
+
second.keys[0] => second[second.keys[0]]
|
259
|
+
}
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Stack data structure
|
264
|
+
# Worst-Case Space Complexity: O(n)
|
265
|
+
class Stack
|
266
|
+
def initialize(size, array=[])
|
267
|
+
@size = size
|
268
|
+
@store = Array.new(@size)
|
269
|
+
@top = -1
|
270
|
+
array.each { |el| push(el) }
|
271
|
+
end
|
272
|
+
|
273
|
+
# Search, Average-Case Time Complexity: O(n)
|
274
|
+
# Search, Worst-Case Time Complexity: O(n)
|
275
|
+
def search(target)
|
276
|
+
found = false
|
277
|
+
new_stack = Stack.new(@size)
|
278
|
+
until empty? do
|
279
|
+
new_stack.push(pop)
|
280
|
+
if new_stack.look == target
|
281
|
+
found = true
|
282
|
+
break
|
283
|
+
end
|
284
|
+
end
|
285
|
+
push(new_stack.pop) until new_stack.empty?
|
286
|
+
found
|
287
|
+
end
|
288
|
+
|
289
|
+
# Deletion, Worst-Case Time Complexity: O(1)
|
290
|
+
def pop
|
291
|
+
if empty?
|
292
|
+
nil
|
293
|
+
else
|
294
|
+
popped = @store[@top]
|
295
|
+
@store[@top] = nil
|
296
|
+
@top = @top.pred
|
297
|
+
popped
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# Insertion, Worst-Case Time Complexity: O(1)
|
302
|
+
def push(el)
|
303
|
+
if full? or el.nil?
|
304
|
+
nil
|
305
|
+
else
|
306
|
+
@top = @top.succ
|
307
|
+
@store[@top] = el
|
308
|
+
self
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def size
|
313
|
+
@size
|
314
|
+
end
|
315
|
+
|
316
|
+
def look
|
317
|
+
@store[@top]
|
318
|
+
end
|
319
|
+
|
320
|
+
def full?
|
321
|
+
@top == (@size - 1)
|
322
|
+
end
|
323
|
+
|
324
|
+
def empty?
|
325
|
+
@top == -1
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# Queue data structure
|
330
|
+
# Worst-Case Space Complexity: O(n)
|
331
|
+
class Queue
|
332
|
+
def initialize(size, array=[])
|
333
|
+
@size = size
|
334
|
+
@store = Array.new(@size)
|
335
|
+
@head, @tail = -1, 0
|
336
|
+
|
337
|
+
# initialize Queue with array if given
|
338
|
+
array.each { |el| enqueue(el) }
|
339
|
+
end
|
340
|
+
|
341
|
+
# Search, Worst-Case Time Complexity: O(n)
|
342
|
+
def search(target)
|
343
|
+
found = false
|
344
|
+
@size.times do
|
345
|
+
found = true if look == target
|
346
|
+
enqueue(dequeue)
|
347
|
+
end
|
348
|
+
found
|
349
|
+
end
|
350
|
+
|
351
|
+
# Deletion, Worst-Case Time Complexity: O(1)
|
352
|
+
def dequeue
|
353
|
+
if empty?
|
354
|
+
nil
|
355
|
+
else
|
356
|
+
@tail = @tail.succ
|
357
|
+
dequeued = @store[@head]
|
358
|
+
@store.unshift(nil)
|
359
|
+
@store.pop
|
360
|
+
dequeued
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
# Insertion, Worst-Case Time Complexity: O(1)
|
365
|
+
def enqueue(el)
|
366
|
+
if full? or el.nil?
|
367
|
+
nil
|
368
|
+
else
|
369
|
+
@tail = @tail.pred
|
370
|
+
@store[@tail] = el
|
371
|
+
self
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def size
|
376
|
+
@size
|
377
|
+
end
|
378
|
+
|
379
|
+
def look
|
380
|
+
@store[@head]
|
381
|
+
end
|
382
|
+
|
383
|
+
private
|
384
|
+
|
385
|
+
def empty?
|
386
|
+
@head == -1 and @tail == 0
|
387
|
+
end
|
388
|
+
|
389
|
+
def full?
|
390
|
+
@tail.abs == (@size)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
# Singly-Linked List data structure
|
395
|
+
# Worst-Case Space Complexity: O(n)
|
396
|
+
class LinkedList
|
397
|
+
include Enumerable
|
398
|
+
|
399
|
+
def initialize(array=[])
|
400
|
+
@head = LinkNode.new
|
401
|
+
@tail = LinkNode.new
|
402
|
+
@head.next = @tail
|
403
|
+
@tail.prev = @head
|
404
|
+
array.each { |i| insert(i) }
|
405
|
+
end
|
406
|
+
|
407
|
+
# Search, Worst-Case Time Complexity: O(n)
|
408
|
+
def search(target)
|
409
|
+
each { |current_link| return current_link.val if current_link.val == target }
|
410
|
+
end
|
411
|
+
|
412
|
+
def [](i)
|
413
|
+
each_with_index { |link, j| return link if i == j }
|
414
|
+
nil
|
415
|
+
end
|
416
|
+
|
417
|
+
def first
|
418
|
+
empty? ? nil : @head.next
|
419
|
+
end
|
420
|
+
|
421
|
+
def last
|
422
|
+
empty? ? nil : @tail.prev
|
423
|
+
end
|
424
|
+
|
425
|
+
def empty?
|
426
|
+
@head.next == @tail
|
427
|
+
end
|
428
|
+
|
429
|
+
def get(val)
|
430
|
+
each { |link| return link.val if link.val == val }
|
431
|
+
nil
|
432
|
+
end
|
433
|
+
|
434
|
+
def include?(val)
|
435
|
+
any? { |link| link.val == val }
|
436
|
+
end
|
437
|
+
|
438
|
+
# Insertion, Worst-Case Time Complexity: O(1)
|
439
|
+
def insert(val)
|
440
|
+
each { |link| return link.val = val if link.val == val }
|
441
|
+
new_link = LinkNode.new(val)
|
442
|
+
@tail.prev.next = new_link
|
443
|
+
new_link.prev = @tail.prev
|
444
|
+
new_link.next = @tail
|
445
|
+
@tail.prev = new_link
|
446
|
+
new_link
|
447
|
+
end
|
448
|
+
|
449
|
+
# Deletion, Worst-Case Time Complexity: O(1)
|
450
|
+
def remove(val)
|
451
|
+
each do |link|
|
452
|
+
if link.val == val
|
453
|
+
link.prev.next = link.next
|
454
|
+
link.next.prev = link.prev
|
455
|
+
link.next, link.prev = nil, nil
|
456
|
+
return link.val
|
457
|
+
end
|
458
|
+
end
|
459
|
+
nil
|
460
|
+
end
|
461
|
+
|
462
|
+
def each
|
463
|
+
current_link = @head.next
|
464
|
+
until current_link == @tail
|
465
|
+
yield current_link
|
466
|
+
current_link = current_link.next
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
# Binary Search Tree data structure
|
472
|
+
# Worst-Case Space Complexity: O(n)
|
473
|
+
class BinaryTree
|
474
|
+
attr_accessor :root
|
475
|
+
|
476
|
+
def initialize(array=[], root_val=nil)
|
477
|
+
@root = BSTNode.new(root_val)
|
478
|
+
array.each { |i| insert(i) }
|
479
|
+
end
|
480
|
+
|
481
|
+
# Search, Worst-Case Time Complexity: O(n)
|
482
|
+
def search(target)
|
483
|
+
return nil if @root.nil?
|
484
|
+
return search_in_tree(@root, target)
|
485
|
+
end
|
486
|
+
|
487
|
+
def search_in_tree(tree_node, target)
|
488
|
+
return nil if tree_node.nil?
|
489
|
+
return tree_node.val if target == tree_node.val
|
490
|
+
if target < tree_node.val
|
491
|
+
search_in_tree(tree_node.left, target)
|
492
|
+
else
|
493
|
+
search_in_tree(tree_node.right, target)
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# Insertion, Worst-Case Time Complexity: O(n)
|
498
|
+
def insert(val)
|
499
|
+
new_node = BSTNode.new(val)
|
500
|
+
@root = new_node and return unless @root.val
|
501
|
+
insert_to_tree(@root, new_node)
|
502
|
+
end
|
503
|
+
|
504
|
+
def insert_to_tree(tree_node, new_node)
|
505
|
+
tree_node = new_node and return if tree_node.nil?
|
506
|
+
return tree_node if tree_node.val == new_node.val
|
507
|
+
if new_node.val > tree_node.val
|
508
|
+
insert_to_tree(tree_node.right, new_node) unless tree_node.right.nil?
|
509
|
+
tree_node.right = new_node
|
510
|
+
else
|
511
|
+
insert_to_tree(tree_node.left, new_node) unless tree_node.left.nil?
|
512
|
+
tree_node.left = new_node
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
private
|
518
|
+
|
519
|
+
# Helper method to get time required for method to run
|
520
|
+
def display_time(prc, num_tests)
|
521
|
+
total = 0
|
522
|
+
num_tests.times do
|
523
|
+
start = Time.now
|
524
|
+
prc.call
|
525
|
+
finish = Time.now
|
526
|
+
total = total + (finish - start)
|
527
|
+
end
|
528
|
+
total/num_tests
|
529
|
+
end
|
530
|
+
|
531
|
+
# Helper method for merge_sort
|
532
|
+
def merge(left, right)
|
533
|
+
array = []
|
534
|
+
until left.length == 0 || right.length == 0
|
535
|
+
if left.first > right.first
|
536
|
+
array << right.shift
|
537
|
+
else
|
538
|
+
array << left.shift
|
539
|
+
end
|
540
|
+
end
|
541
|
+
array.concat(left).concat(right)
|
542
|
+
end
|
543
|
+
|
544
|
+
# Node helper class for Linked List
|
545
|
+
class LinkNode
|
546
|
+
attr_accessor :val, :next, :prev
|
547
|
+
def initialize(val=nil)
|
548
|
+
@val = val
|
549
|
+
@next = nil
|
550
|
+
@prev = nil
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
# Node helper class for Binary Search Tree
|
555
|
+
class BSTNode
|
556
|
+
attr_accessor :val, :left, :right
|
557
|
+
def initialize(val=nil, left=nil, right=nil)
|
558
|
+
@val = val
|
559
|
+
@left = left
|
560
|
+
@right = right
|
561
|
+
end
|
562
|
+
end
|