algorithmix 0.0.0.4 → 0.0.0.4.1
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.
- checksums.yaml +4 -4
- data/algorithmix.gemspec +5 -5
- data/lib/algorithmix/data_structure/heap/binary_heap.rb +452 -0
- data/lib/algorithmix/version.rb +1 -1
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d842f0aaccbd42b0b889d9eb1f3e8c7dac5d84a
|
4
|
+
data.tar.gz: 7908a79a6005b07d6aa97f50ece276b0d4a33650
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3ce32ef804f089f1db22aed4749e953fa643156dd8d482af0dffd9670bf74aa3fa066a0b36862d12ea69c0849e0d30e3501051ff6e25c94cb9f74f0d6cefec8
|
7
|
+
data.tar.gz: 66983d3763e7d7b29c0562b7a2ad6df3289c0664b769d13e21013443dfc26ea3ab8589f091d2e77733bfffa5e048886aa529d6d5ad01cfc98bb28c7e41b45b80
|
data/algorithmix.gemspec
CHANGED
@@ -10,11 +10,11 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["*@*.*"]
|
11
11
|
spec.summary = %q{The gem contains various implementations of known and uknown data structures and algorithms}
|
12
12
|
spec.description = <<-DOC
|
13
|
-
Currently the gem contains
|
14
|
-
1. Stack
|
15
|
-
2. Queue
|
16
|
-
3. Deque
|
17
|
-
4. Binary heap
|
13
|
+
Currently the gem contains:\n
|
14
|
+
1. Stack\n
|
15
|
+
2. Queue\n
|
16
|
+
3. Deque\n
|
17
|
+
4. Binary heap\n
|
18
18
|
|
19
19
|
DOC
|
20
20
|
spec.homepage = "https://github.com/monzita/algorithmix/wiki"
|
@@ -0,0 +1,452 @@
|
|
1
|
+
# Documentation: https://github.com/monzita/algorithmix/wiki/BinaryHeap
|
2
|
+
|
3
|
+
module Algorithmix
|
4
|
+
module DataStructure
|
5
|
+
module Heap
|
6
|
+
|
7
|
+
class BinaryHeap
|
8
|
+
|
9
|
+
# Creates a new binary heap.
|
10
|
+
#
|
11
|
+
# @param obj [#to_a] can be any object, which responds to #to_a method. By default is set to nil.
|
12
|
+
# @kwarg copy [true, false] if is set to true, content of the object will be copied into content of the new heap.
|
13
|
+
# By default is set to false.
|
14
|
+
# @kwarg min [true, false] defines the type of the new heap, be default min is set to false
|
15
|
+
# @raise ArgumentError, if given object doesn't respond to #to_a method.
|
16
|
+
# @return [BinaryHeap] a newly created binary heap
|
17
|
+
def initialize(obj = nil, copy: false, min: false)
|
18
|
+
@container = []
|
19
|
+
@max = min ? false : true
|
20
|
+
obj.nil? ? nil : from_obj(obj, copy)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Assigns content of an object, to content of the heap.
|
24
|
+
#
|
25
|
+
# @param obj [#to_a] can be any object, which responds to #to_a method. By default is set to nil.
|
26
|
+
# @kwarg copy [true, false] if is set to true, content of the object will be copied into content of the new heap.
|
27
|
+
# By default is set to false.
|
28
|
+
# @raise ArgumentError, if given object doesn't respond to #to_a method.
|
29
|
+
# @return [BinaryHeap] self object
|
30
|
+
def assign(obj, copy: false)
|
31
|
+
from_obj(obj, copy)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Inserts a value in the heap.
|
35
|
+
#
|
36
|
+
# @param value
|
37
|
+
# @return [BinaryHeap] self object
|
38
|
+
def insert(value)
|
39
|
+
@container << value
|
40
|
+
sift_up(@container.size - 1)
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# (see #insert)
|
45
|
+
def <<(value)
|
46
|
+
insert(value)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Removes top element of the heap.
|
50
|
+
#
|
51
|
+
# @raise Algorithmix::EmptyContainerError, if the heap is empty.
|
52
|
+
# @return top element of the heap.
|
53
|
+
def extract
|
54
|
+
raise EmptyContainerError, "The Binary heap is empty." if @container.empty?
|
55
|
+
@container[0], @container[@container.length - 1] = @container[@container.length - 1], @container[0]
|
56
|
+
value = @container.pop
|
57
|
+
heapify(0)
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns top element of the heap, without removing it.
|
62
|
+
#
|
63
|
+
# @return top element.
|
64
|
+
def top
|
65
|
+
@container.first
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns number of elements in the heap.
|
69
|
+
def size
|
70
|
+
@container.size
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns information for current ...
|
74
|
+
def empty?
|
75
|
+
@container.empty?
|
76
|
+
end
|
77
|
+
|
78
|
+
# Increases a value in the heap, if current heap is set to be max heap.
|
79
|
+
#
|
80
|
+
# @kwarg idx [Integer] any integer, which can represent index at an array.
|
81
|
+
# @krarg old_value
|
82
|
+
# @kwarg new_value
|
83
|
+
# @raise TypeError, if current heap has type min heap
|
84
|
+
# @raise ArgumentError, if idx or old_value are not provided
|
85
|
+
# @raise ArgumentError, if new_value is not provided
|
86
|
+
# @return [BinaryHeap] self object
|
87
|
+
def increase_key(idx: nil, old_value: nil, new_value: nil)
|
88
|
+
raise TypeError, "Undefined method BinaryHeap#increase_key for MinBinaryHeap" if !@max
|
89
|
+
raise ArgumentError, "At least one of both options must be provided." if idx.nil? && old_value.nil?
|
90
|
+
raise ArgumentError, ":new_value cannot be nil." if new_value.nil?
|
91
|
+
|
92
|
+
idx = idx.nil? && !old_value.nil? ? @container.index(old_value) : idx
|
93
|
+
raise ArgumentError, "Element at position #{idx} doesn't exist." if idx.nil? || @container[idx].nil?
|
94
|
+
change_key(idx, new_value, increase: true)
|
95
|
+
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Decreases a value in the heap, if current heap is set to be min heap.
|
101
|
+
#
|
102
|
+
# @kwarg idx [Integer] any integer, which can represent index at an array.
|
103
|
+
# @krarg old_value
|
104
|
+
# @kwarg new_value
|
105
|
+
# @raise TypeError, if current heap has type max heap
|
106
|
+
# @raise ArgumentError, if idx or old_value are not provided
|
107
|
+
# @raise ArgumentError, if new_value is not provided
|
108
|
+
# @return [BinaryHeap] self object
|
109
|
+
def decrease_key(idx: nil, old_value: nil, new_value: nil)
|
110
|
+
raise TypeError, "Undefined method BinaryHeap#decrease_key for MaxBinaryHeap" if @max
|
111
|
+
raise ArgumentError, "At least one of both options must be provided." if idx.nil? && old_value.nil?
|
112
|
+
raise ArgumentError, ":new_value cannot be nil." if new_value.nil?
|
113
|
+
|
114
|
+
idx = idx.nil? && !old_value.nil? ? @container.index(old_value) : idx
|
115
|
+
raise ArgumentError, "Element at position #{idx} doesn't exist." if idx.nil? || @container[idx].nil?
|
116
|
+
change_key(idx, new_value)
|
117
|
+
|
118
|
+
self
|
119
|
+
end
|
120
|
+
|
121
|
+
# Compares contents of the heap, and a heap given as argument.
|
122
|
+
#
|
123
|
+
# @param binary_heap [BinaryHeap]
|
124
|
+
# @raise ArgumentError, if given object is not a heap.
|
125
|
+
# @return [true, false] true if heaps are equal, false otherwise
|
126
|
+
def ==(binary_heap)
|
127
|
+
raise ArgumentError, "Undefined method BinaryHeap#== for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
128
|
+
@container == binary_heap.to_a
|
129
|
+
end
|
130
|
+
|
131
|
+
# (see #==)
|
132
|
+
def eql?(binary_heap)
|
133
|
+
raise ArgumentError, "Undefined method BinaryHeap#eql? for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
134
|
+
self == binary_heap
|
135
|
+
end
|
136
|
+
|
137
|
+
# Compares contents of the heap, and a heap given as argument.
|
138
|
+
#
|
139
|
+
# @param binary_heap [BinaryHeap]
|
140
|
+
# @raise ArgumentError, if given object is not a heap.
|
141
|
+
# @return [true, false] false if heaps are equal, true otherwise
|
142
|
+
def !=(binary_heap)
|
143
|
+
raise ArgumentError, "Undefined method BinaryHeap#!= for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
144
|
+
@container != binary_heap.to_a
|
145
|
+
end
|
146
|
+
|
147
|
+
# (see #!=)
|
148
|
+
def diff?(binary_heap)
|
149
|
+
raise ArgumentError, "Undefined method BinaryHeap#diff? for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
150
|
+
self != binary_heap
|
151
|
+
end
|
152
|
+
|
153
|
+
# Compares contents of the heap, and a heap given as argument.
|
154
|
+
#
|
155
|
+
# @param binary_heap [BinaryHeap]
|
156
|
+
# @raise ArgumentError, if given object is not a heap.
|
157
|
+
# @return
|
158
|
+
# => 1 if content of the heap is greater than content of the given heap
|
159
|
+
# => 0 if contents are equal
|
160
|
+
# => -1 if content of the given heap is greater than content of the heap
|
161
|
+
def <=>(binary_heap)
|
162
|
+
raise ArgumentError, "Undefined method BinaryHeap#<=> for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
163
|
+
@container <=> binary_heap.to_a
|
164
|
+
end
|
165
|
+
|
166
|
+
# Concatenates contents of the heap, and a heap given as argument.
|
167
|
+
#
|
168
|
+
# @param binary_heap [BinaryHeap]
|
169
|
+
# @raise ArgumentError, if given object is not a heap
|
170
|
+
# @return [BinaryHeap] a new binary heap
|
171
|
+
def +(binary_heap)
|
172
|
+
raise ArgumentError, "Undefined method BinaryHeap#+ for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
173
|
+
|
174
|
+
BinaryHeap.new(@container + binary_heap.to_a, min: !@max)
|
175
|
+
end
|
176
|
+
|
177
|
+
# (see #+)
|
178
|
+
def concat(binary_heap)
|
179
|
+
raise ArgumentError, "Undefined method BinaryHeap#concat for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
180
|
+
self + binary_heap
|
181
|
+
end
|
182
|
+
|
183
|
+
# (see #+)
|
184
|
+
def merge(binary_heap)
|
185
|
+
raise ArgumentError, "Undefined method BinaryHeap#merge for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
186
|
+
self + binary_heap
|
187
|
+
end
|
188
|
+
|
189
|
+
# Concatenates contents of the heap, and a heap given as argument.
|
190
|
+
#
|
191
|
+
# @param binary_heap [BinaryHeap]
|
192
|
+
# @raise ArgumentError, if given object is not a heap
|
193
|
+
# @return [BinaryHeap] self object
|
194
|
+
def concat!(binary_heap)
|
195
|
+
raise ArgumentError, "Undefined method BinaryHeap#concat! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
196
|
+
from_obj(@container + binary_heap.to_a, false)
|
197
|
+
end
|
198
|
+
|
199
|
+
# Concatenates contents of the heap, and a heap given as argument.
|
200
|
+
#
|
201
|
+
# @param binary_heap [BinaryHeap]
|
202
|
+
# @raise ArgumentError, if given object is not a heap
|
203
|
+
# @return [BinaryHeap] self object
|
204
|
+
def merge!(binary_heap)
|
205
|
+
raise ArgumentError, "Undefined method BinaryHeap#merge! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
206
|
+
from_obj(@container + binary_heap.to_a, false)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Unites contents of the heap, and a heap given as argument.
|
210
|
+
#
|
211
|
+
# @param binary_heap [BinaryHeap]
|
212
|
+
# @raise ArgumentError, if given object is not a heap
|
213
|
+
# @return [BinaryHeap] a new binary heap
|
214
|
+
def |(binary_heap)
|
215
|
+
raise ArgumentError, "Undefined method BinaryHeap#| for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
216
|
+
BinaryHeap.new(@container | binary_heap.to_a, min: !@max)
|
217
|
+
end
|
218
|
+
|
219
|
+
# (see #|)
|
220
|
+
def union(binary_heap)
|
221
|
+
raise ArgumentError, "Undefined method BinaryHeap#union for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
222
|
+
self | binary_heap
|
223
|
+
end
|
224
|
+
|
225
|
+
# Unites contents of the heap, and a heap given as argument.
|
226
|
+
#
|
227
|
+
# @param binary_heap [BinaryHeap]
|
228
|
+
# @raise ArgumentError, if given object is not a heap
|
229
|
+
# @return [BinaryHeap] self object
|
230
|
+
def union!(binary_heap)
|
231
|
+
raise ArgumentError, "Undefined method BinaryHeap#union! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
232
|
+
from_obj(@container | binary_heap.to_a, false)
|
233
|
+
end
|
234
|
+
|
235
|
+
# Finds the intersection of contents of the heap, and a heap given as argument.
|
236
|
+
#
|
237
|
+
# @param binary_heap [BinaryHeap]
|
238
|
+
# @raise ArgumentError, if given object is not a heap
|
239
|
+
# @return [BinaryHeap] a new binary heap
|
240
|
+
def &(binary_heap)
|
241
|
+
raise ArgumentError, "Undefined method BinaryHeap#& for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
242
|
+
BinaryHeap.new(@container & binary_heap.to_a, min: !@max)
|
243
|
+
end
|
244
|
+
|
245
|
+
# (see #&)
|
246
|
+
def intersect(binary_heap)
|
247
|
+
raise ArgumentError, "Undefined method BinaryHeap#intersect for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
248
|
+
self & binary_heap.to_a
|
249
|
+
end
|
250
|
+
|
251
|
+
# Finds the intersection of contents of the heap, and a heap given as argument.
|
252
|
+
#
|
253
|
+
# @param binary_heap [BinaryHeap]
|
254
|
+
# @raise ArgumentError, if given object is not a heap
|
255
|
+
# @return [BinaryHeap] self object
|
256
|
+
def intersect!(binary_heap)
|
257
|
+
raise ArgumentError, "Undefined method BinaryHeap#intersect! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
258
|
+
from_obj(@container & binary_heap.to_a, false)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Finds the difference of contents of the heap, and a heap given as argument.
|
262
|
+
#
|
263
|
+
# @param binary_heap [BinaryHeap]
|
264
|
+
# @raise ArgumentError, if given object is not a heap
|
265
|
+
# @return [BinaryHeap] a new binary heap
|
266
|
+
def -(binary_heap)
|
267
|
+
raise ArgumentError, "Undefined method BinaryHeap#- for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
268
|
+
BinaryHeap.new(@container - binary_heap.to_a, min: !@max)
|
269
|
+
end
|
270
|
+
|
271
|
+
# (see #-)
|
272
|
+
def difference(binary_heap)
|
273
|
+
raise ArgumentError, "Undefined method BinaryHeap#difference for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
274
|
+
self - binary_heap
|
275
|
+
end
|
276
|
+
|
277
|
+
# Finds the difference of contents of the heap, and a heap given as argument.
|
278
|
+
#
|
279
|
+
# @param binary_heap [BinaryHeap]
|
280
|
+
# @raise ArgumentError, if given object is not a heap
|
281
|
+
# @return [BinaryHeap] self object
|
282
|
+
def difference!(binary_heap)
|
283
|
+
raise ArgumentError, "Undefined method BinaryHeap#difference! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
284
|
+
from_obj(@container - binary_heap.to_a, false)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Finds the symmetric difference of contents of the heap, and a heap given as argument.
|
288
|
+
#
|
289
|
+
# @param binary_heap [BinaryHeap]
|
290
|
+
# @raise ArgumentError, if given object is not a heap
|
291
|
+
# @return [BinaryHeap] a new binary heap
|
292
|
+
def ^(binary_heap)
|
293
|
+
raise ArgumentError, "Undefined method BinaryHeap#^ for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
294
|
+
result = (@container | binary_heap.to_a) - (@container & binary_heap.to_a)
|
295
|
+
BinaryHeap.new(result, min: !@max)
|
296
|
+
end
|
297
|
+
|
298
|
+
# (see #^)
|
299
|
+
def symmetric_difference(binary_heap)
|
300
|
+
raise ArgumentError, "Undefined method BinaryHeap#symmetric_difference for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
301
|
+
self ^ binary_heap
|
302
|
+
end
|
303
|
+
|
304
|
+
# Finds the symmetric difference of contents of the heap, and a heap given as argument.
|
305
|
+
#
|
306
|
+
# @param binary_heap [BinaryHeap]
|
307
|
+
# @raise ArgumentError, if given object is not a heap
|
308
|
+
# @return [BinaryHeap] self object
|
309
|
+
def symmetric_difference!(binary_heap)
|
310
|
+
raise ArgumentError, "Undefined method BinaryHeap#symmetric_difference! for #{binary_heap}:#{binary_heap.class}" unless binary_heap.is_a?(BinaryHeap)
|
311
|
+
result = (@container | binary_heap.to_a) - (@container & binary_heap.to_a)
|
312
|
+
from_obj(result, false)
|
313
|
+
end
|
314
|
+
|
315
|
+
# Converts content of the heap to an array.
|
316
|
+
def to_a
|
317
|
+
@container
|
318
|
+
end
|
319
|
+
|
320
|
+
# Clears content of the heap.
|
321
|
+
def clear
|
322
|
+
@container = []
|
323
|
+
self
|
324
|
+
end
|
325
|
+
|
326
|
+
# Filters elements of the heap by given condition.
|
327
|
+
#
|
328
|
+
# @param block
|
329
|
+
# @return [BinaryHeap] a new binary heap
|
330
|
+
def select(&block)
|
331
|
+
BinaryHeap.new(@container.select { |e| block.call(e)}, min: !@max)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Filters elements of the heap by given condition.
|
335
|
+
#
|
336
|
+
# @param block
|
337
|
+
# @return [BinaryHeap] self object
|
338
|
+
def select!(&block)
|
339
|
+
from_obj(@container.select { |e| block.call(e)}, false)
|
340
|
+
end
|
341
|
+
|
342
|
+
# (see #select)
|
343
|
+
def filter(&block)
|
344
|
+
select(&block)
|
345
|
+
end
|
346
|
+
|
347
|
+
# (see #select!)
|
348
|
+
def filter!(&block)
|
349
|
+
select!(&block)
|
350
|
+
end
|
351
|
+
|
352
|
+
# (see #select)
|
353
|
+
def find_all(&block)
|
354
|
+
select(&block)
|
355
|
+
end
|
356
|
+
|
357
|
+
# (see #select!)
|
358
|
+
def find_all!(&block)
|
359
|
+
select!(&block)
|
360
|
+
end
|
361
|
+
|
362
|
+
# Applies a function to each element of the heap.
|
363
|
+
#
|
364
|
+
# @param block
|
365
|
+
# @return [BinaryHeap] a new binary heap
|
366
|
+
def map(&block)
|
367
|
+
BinaryHeap.new(@container.map { |e| block.call(e)}, min: !@max)
|
368
|
+
end
|
369
|
+
|
370
|
+
# Applies a function to each element of the heap.
|
371
|
+
#
|
372
|
+
# @param block
|
373
|
+
# @return [BinaryHeap] self object
|
374
|
+
def map!(&block)
|
375
|
+
from_obj(@container.map { |e| block.call(e)}, false)
|
376
|
+
end
|
377
|
+
|
378
|
+
# (see #map)
|
379
|
+
def apply(&block)
|
380
|
+
map(&block)
|
381
|
+
end
|
382
|
+
|
383
|
+
# (see #map!)
|
384
|
+
def apply!(&block)
|
385
|
+
map!(&block)
|
386
|
+
end
|
387
|
+
|
388
|
+
private
|
389
|
+
|
390
|
+
def from_obj(obj, copy)
|
391
|
+
raise ArgumentError, "Object doesn't respond to #to_a method" unless obj.respond_to?(:to_a)
|
392
|
+
@container = copy ? obj.send(:to_a).dup : obj.send(:to_a)
|
393
|
+
|
394
|
+
build_heap
|
395
|
+
self
|
396
|
+
end
|
397
|
+
|
398
|
+
def heapify(idx)
|
399
|
+
return if idx.nil?
|
400
|
+
lhs = idx * 2 + 1
|
401
|
+
rhs = idx * 2 + 2
|
402
|
+
current = idx
|
403
|
+
|
404
|
+
if !@container[lhs].nil? &&
|
405
|
+
((@max && @container[lhs] > @container[current]) ||
|
406
|
+
(!@max && @container[lhs] < @container[current]))
|
407
|
+
|
408
|
+
current = lhs
|
409
|
+
end
|
410
|
+
|
411
|
+
if !@container[rhs].nil? &&
|
412
|
+
((@max && @container[rhs] > @container[current]) ||
|
413
|
+
(!@max && @container[rhs] < @container[current]))
|
414
|
+
|
415
|
+
current = rhs
|
416
|
+
end
|
417
|
+
|
418
|
+
if current != idx
|
419
|
+
@container[idx], @container[current] = @container[current], @container[idx]
|
420
|
+
heapify(current)
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
def build_heap
|
425
|
+
(@container.length / 2).downto(0) do |idx|
|
426
|
+
heapify(idx)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def sift_up(idx)
|
431
|
+
return if idx.zero?
|
432
|
+
parent = idx.even? ? idx / 2 - 1 : idx / 2
|
433
|
+
|
434
|
+
if (@max && @container[parent] < @container[idx]) || (!@max && @container[parent] > @container[idx])
|
435
|
+
@container[parent], @container[idx] = @container[idx], @container[parent]
|
436
|
+
|
437
|
+
sift_up(parent)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
def change_key(idx, value, increase: false)
|
442
|
+
idx = idx < 0 ? idx + @container.size : idx
|
443
|
+
@container[idx] = increase ? (@container[idx] < value ? value : @container[idx]) :
|
444
|
+
(@container[idx] > value ? value : @container[idx])
|
445
|
+
|
446
|
+
sift_up(idx)
|
447
|
+
end
|
448
|
+
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
data/lib/algorithmix/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algorithmix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.0.4
|
4
|
+
version: 0.0.0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Monika Ilieva
|
@@ -68,11 +68,16 @@ dependencies:
|
|
68
68
|
version: 2.0.0
|
69
69
|
description: |2+
|
70
70
|
Currently the gem contains:
|
71
|
+
|
71
72
|
1. Stack
|
73
|
+
|
72
74
|
2. Queue
|
75
|
+
|
73
76
|
3. Deque
|
77
|
+
|
74
78
|
4. Binary heap
|
75
79
|
|
80
|
+
|
76
81
|
email:
|
77
82
|
- "*@*.*"
|
78
83
|
executables: []
|
@@ -94,6 +99,7 @@ files:
|
|
94
99
|
- lib/algorithmix/data_structure/generic/deque.rb
|
95
100
|
- lib/algorithmix/data_structure/generic/queue.rb
|
96
101
|
- lib/algorithmix/data_structure/generic/stack.rb
|
102
|
+
- lib/algorithmix/data_structure/heap/binary_heap.rb
|
97
103
|
- lib/algorithmix/error.rb
|
98
104
|
- lib/algorithmix/version.rb
|
99
105
|
homepage: https://github.com/monzita/algorithmix/wiki
|