algorithmix 0.0.0.4 → 0.0.0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|