depq 0.2 → 0.3
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.
- data/README +59 -47
- data/depq.rb +452 -470
- data/test-depq.rb +599 -368
- metadata +1 -1
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Depq - Feature Rich Double-Ended Priority Queue.
|
1
|
+
= Depq - Feature Rich Double-Ended Priority Queue.
|
2
2
|
|
3
3
|
= Features
|
4
4
|
|
@@ -9,6 +9,18 @@ Depq - Feature Rich Double-Ended Priority Queue.
|
|
9
9
|
* update priority - usable for Dijkstra's shortest path algorithm and various graph algorithms
|
10
10
|
* implicit binary heap - most operations are O(log n) at worst
|
11
11
|
|
12
|
+
= Install
|
13
|
+
|
14
|
+
gem install depq
|
15
|
+
|
16
|
+
= Links
|
17
|
+
|
18
|
+
* ((<reference manual|URL:http://depq.rubyforge.org/rdoc/classes/Depq.html>))
|
19
|
+
* ((<home page on rubyforge|URL:http://depq.rubyforge.org/>))
|
20
|
+
* ((<project info on rubyforge|URL:http://rubyforge.org/projects/depq/>))
|
21
|
+
* ((<source repository on github|URL:http://github.com/akr/depq>))
|
22
|
+
* ((<raa entry|URL:http://raa.ruby-lang.org/project/depq/>))
|
23
|
+
|
12
24
|
= Introduction
|
13
25
|
|
14
26
|
== Simple Insertion/Deletion
|
@@ -18,18 +30,18 @@ You can deletes the values from the object from ascending/descending order.
|
|
18
30
|
delete_min deletes the minimum value.
|
19
31
|
It is used for ascending order.
|
20
32
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
p
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
p
|
29
|
-
p
|
30
|
-
p
|
31
|
-
p
|
32
|
-
p
|
33
|
+
q = Depq.new
|
34
|
+
q.insert "durian"
|
35
|
+
q.insert "banana"
|
36
|
+
p q.delete_min #=> "banana"
|
37
|
+
q.insert "orange"
|
38
|
+
q.insert "apple"
|
39
|
+
q.insert "melon"
|
40
|
+
p q.delete_min #=> "apple"
|
41
|
+
p q.delete_min #=> "durian"
|
42
|
+
p q.delete_min #=> "melon"
|
43
|
+
p q.delete_min #=> "orange"
|
44
|
+
p q.delete_min #=> nil
|
33
45
|
|
34
46
|
delete_max is similar to delete_min except it deletes maximum element
|
35
47
|
instead of minimum.
|
@@ -37,17 +49,17 @@ It is used for descending order.
|
|
37
49
|
|
38
50
|
== The Order
|
39
51
|
|
40
|
-
The order is defined by the priorities
|
52
|
+
The order is defined by the priorities corresponds to the values and
|
41
53
|
comparison operator specified for the queue.
|
42
54
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
p
|
48
|
-
p
|
49
|
-
p
|
50
|
-
p
|
55
|
+
q = Depq.new(:casecmp) # use casecmp instead of <=>.
|
56
|
+
q.insert 1, "Foo" # specify the priority for 1 as "Foo"
|
57
|
+
q.insert 2, "bar"
|
58
|
+
q.insert 3, "Baz"
|
59
|
+
p q.delete_min #=> 2 # "bar" is minimum
|
60
|
+
p q.delete_min #=> 3
|
61
|
+
p q.delete_min #=> 1 # "Foo" is maximum
|
62
|
+
p q.delete_min #=> nil
|
51
63
|
|
52
64
|
If there are multiple values with same priority, subpriority is used to compare them.
|
53
65
|
subpriority is an integer which can be specified by 3rd argument of insert.
|
@@ -55,19 +67,19 @@ If it is not specified, total number of inserted elements is used.
|
|
55
67
|
So Depq is "stable" with delete_min.
|
56
68
|
The element inserted first is minimum and deleted first.
|
57
69
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
p
|
66
|
-
p
|
67
|
-
p
|
68
|
-
p
|
69
|
-
p
|
70
|
-
p
|
70
|
+
q = Depq.new
|
71
|
+
q.insert "a", 1 # "a", "c" and "e" has same priority: 1
|
72
|
+
q.insert "b", 0 # "b", "d" and "f" has same priority: 0
|
73
|
+
q.insert "c", 1
|
74
|
+
q.insert "d", 0
|
75
|
+
q.insert "e", 1
|
76
|
+
q.insert "f", 0
|
77
|
+
p q.delete_min #=> "b" first element with priority 0
|
78
|
+
p q.delete_min #=> "d"
|
79
|
+
p q.delete_min #=> "f" last element with priority 0
|
80
|
+
p q.delete_min #=> "a" first element with priority 1
|
81
|
+
p q.delete_min #=> "c"
|
82
|
+
p q.delete_min #=> "e" last element with priority 1
|
71
83
|
|
72
84
|
Note that delete_max is also stable.
|
73
85
|
This means delete_max deletes the element with maximum priority with "minimum" subpriority.
|
@@ -78,22 +90,22 @@ An inserted element can be modified and/or deleted.
|
|
78
90
|
This is done using Depq::Locator object.
|
79
91
|
It is returned by insert, find_min_locator, etc.
|
80
92
|
|
81
|
-
|
82
|
-
d =
|
83
|
-
m =
|
84
|
-
c =
|
93
|
+
q = Depq.new
|
94
|
+
d = q.insert "durian", 1
|
95
|
+
m = q.insert "mangosteen", 2
|
96
|
+
c = q.insert "cherry", 3
|
85
97
|
p m #=> #<Depq::Locator: "mangosteen":2>
|
86
98
|
p m.value #=> "mangosteen"
|
87
99
|
p m.priority #=> 2
|
88
|
-
p
|
89
|
-
p
|
100
|
+
p q.find_min #=> "durian"
|
101
|
+
p q.find_min_locator #=> #<Depq::Locator: "durian":1>
|
90
102
|
m.update("mangosteen", 0)
|
91
|
-
p
|
92
|
-
p
|
93
|
-
|
94
|
-
p
|
95
|
-
p
|
96
|
-
p
|
103
|
+
p q.find_min #=> "mangosteen"
|
104
|
+
p q.find_min_locator #=> #<Depq::Locator: "mangosteen":0>
|
105
|
+
q.delete_element d
|
106
|
+
p q.delete_min #=> "mangosteen"
|
107
|
+
p q.delete_min #=> "cherry"
|
108
|
+
p q.delete_min #=> nil
|
97
109
|
|
98
110
|
For example, this feature can be used for graph algorithms
|
99
111
|
such as Dijkstra's shortest path finding algorithm,
|
data/depq.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# depq.rb -
|
1
|
+
# depq.rb - Double-Ended Priority Queue.
|
2
2
|
#
|
3
3
|
# Copyright (C) 2009 Tanaka Akira <akr@fsij.org>
|
4
4
|
#
|
@@ -24,7 +24,7 @@
|
|
24
24
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
25
25
|
# OF SUCH DAMAGE.
|
26
26
|
|
27
|
-
# Depq -
|
27
|
+
# Depq - Double-Ended Priority Queue.
|
28
28
|
#
|
29
29
|
# = Features
|
30
30
|
#
|
@@ -44,18 +44,18 @@
|
|
44
44
|
# delete_min deletes the minimum value.
|
45
45
|
# It is used for ascending order.
|
46
46
|
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# p
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
# p
|
55
|
-
# p
|
56
|
-
# p
|
57
|
-
# p
|
58
|
-
# p
|
47
|
+
# q = Depq.new
|
48
|
+
# q.insert "durian"
|
49
|
+
# q.insert "banana"
|
50
|
+
# p q.delete_min #=> "banana"
|
51
|
+
# q.insert "orange"
|
52
|
+
# q.insert "apple"
|
53
|
+
# q.insert "melon"
|
54
|
+
# p q.delete_min #=> "apple"
|
55
|
+
# p q.delete_min #=> "durian"
|
56
|
+
# p q.delete_min #=> "melon"
|
57
|
+
# p q.delete_min #=> "orange"
|
58
|
+
# p q.delete_min #=> nil
|
59
59
|
#
|
60
60
|
# delete_max is similar to delete_min except it deletes maximum element
|
61
61
|
# instead of minimum.
|
@@ -66,14 +66,14 @@
|
|
66
66
|
# The order is defined by the priorities corresnponds to the values and
|
67
67
|
# comparison operator specified for the queue.
|
68
68
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
# p
|
74
|
-
# p
|
75
|
-
# p
|
76
|
-
# p
|
69
|
+
# q = Depq.new(:casecmp) # use casecmp instead of <=>.
|
70
|
+
# q.inesrt 1, "Foo" # specify the priority for 1 as "Foo"
|
71
|
+
# q.insert 2, "bar"
|
72
|
+
# q.insert 3, "Baz"
|
73
|
+
# p q.delete_min #=> 2 # "bar" is minimum
|
74
|
+
# p q.delete_min #=> 3
|
75
|
+
# p q.delete_min #=> 1 # "Foo" is maximum
|
76
|
+
# p q.delete_min #=> nil
|
77
77
|
#
|
78
78
|
# If there are multiple values with same priority, subpriority is used to compare them.
|
79
79
|
# subpriority is an integer which can be specified by 3rd argument of insert.
|
@@ -81,19 +81,19 @@
|
|
81
81
|
# So Depq is "stable" with delete_min.
|
82
82
|
# The element inserted first is minimum and deleted first.
|
83
83
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
# p
|
92
|
-
# p
|
93
|
-
# p
|
94
|
-
# p
|
95
|
-
# p
|
96
|
-
# p
|
84
|
+
# q = Depq.new
|
85
|
+
# q.insert "a", 1 # "a", "c" and "e" has same priority: 1
|
86
|
+
# q.insert "b", 0 # "b", "d" and "f" has same priority: 0
|
87
|
+
# q.insert "c", 1
|
88
|
+
# q.insert "d", 0
|
89
|
+
# q.insert "e", 1
|
90
|
+
# q.insert "f", 0
|
91
|
+
# p q.delete_min #=> "b" first element with priority 0
|
92
|
+
# p q.delete_min #=> "d"
|
93
|
+
# p q.delete_min #=> "f" last element with priority 0
|
94
|
+
# p q.delete_min #=> "a" first element with priority 1
|
95
|
+
# p q.delete_min #=> "c"
|
96
|
+
# p q.delete_min #=> "e" last element with priority 1
|
97
97
|
#
|
98
98
|
# Note that delete_max is also stable.
|
99
99
|
# This means delete_max deletes the element with maximum priority with "minimum" subpriority.
|
@@ -104,22 +104,22 @@
|
|
104
104
|
# This is done using Depq::Locator object.
|
105
105
|
# It is returned by insert, find_min_locator, etc.
|
106
106
|
#
|
107
|
-
#
|
108
|
-
# d =
|
109
|
-
# m =
|
110
|
-
# c =
|
107
|
+
# q = Depq.new
|
108
|
+
# d = q.insert "durian", 1
|
109
|
+
# m = q.insert "mangosteen", 2
|
110
|
+
# c = q.insert "cherry", 3
|
111
111
|
# p m #=> #<Depq::Locator: "mangosteen":2>
|
112
112
|
# p m.value #=> "mangosteen"
|
113
113
|
# p m.priority #=> 2
|
114
|
-
# p
|
115
|
-
# p
|
114
|
+
# p q.find_min #=> "durian"
|
115
|
+
# p q.find_min_locator #=> #<Depq::Locator: "durian":1>
|
116
116
|
# m.update("mangosteen", 0)
|
117
|
-
# p
|
118
|
-
# p
|
119
|
-
#
|
120
|
-
# p
|
121
|
-
# p
|
122
|
-
# p
|
117
|
+
# p q.find_min #=> "mangosteen"
|
118
|
+
# p q.find_min_locator #=> #<Depq::Locator: "mangosteen":0>
|
119
|
+
# q.delete_element d
|
120
|
+
# p q.delete_min #=> "mangosteen"
|
121
|
+
# p q.delete_min #=> "cherry"
|
122
|
+
# p q.delete_min #=> nil
|
123
123
|
#
|
124
124
|
# For example, this feature can be used for graph algorithms
|
125
125
|
# such as Dijkstra's shortest path finding algorithm,
|
@@ -175,22 +175,22 @@
|
|
175
175
|
class Depq
|
176
176
|
include Enumerable
|
177
177
|
|
178
|
-
Locator = Struct.new(:value, :
|
178
|
+
Locator = Struct.new(:value, :depq_or_subpriority, :index_or_priority)
|
179
179
|
class Locator
|
180
180
|
|
181
|
-
# if
|
182
|
-
#
|
181
|
+
# if depq_or_subpriority is Depq
|
182
|
+
# depq_or_subpriority is depq
|
183
183
|
# index_or_priority is index
|
184
184
|
# else
|
185
|
-
#
|
185
|
+
# depq_or_subpriority is subpriority
|
186
186
|
# index_or_priority is priority
|
187
187
|
# end
|
188
188
|
#
|
189
189
|
# only 3 fields for memory efficiency.
|
190
190
|
|
191
191
|
private :value=
|
192
|
-
private :
|
193
|
-
private :
|
192
|
+
private :depq_or_subpriority
|
193
|
+
private :depq_or_subpriority=
|
194
194
|
private :index_or_priority
|
195
195
|
private :index_or_priority=
|
196
196
|
|
@@ -240,16 +240,16 @@ class Depq
|
|
240
240
|
|
241
241
|
# returns true if the locator is in a queue.
|
242
242
|
def in_queue?
|
243
|
-
|
243
|
+
depq_or_subpriority().kind_of? Depq
|
244
244
|
end
|
245
245
|
|
246
246
|
# returns the queue.
|
247
247
|
#
|
248
|
-
# nil is returned if the locator is not in a
|
249
|
-
def
|
250
|
-
in_queue? ?
|
248
|
+
# nil is returned if the locator is not in a depq.
|
249
|
+
def depq
|
250
|
+
in_queue? ? depq_or_subpriority() : nil
|
251
251
|
end
|
252
|
-
alias queue
|
252
|
+
alias queue depq
|
253
253
|
|
254
254
|
def index
|
255
255
|
in_queue? ? index_or_priority() : nil
|
@@ -267,8 +267,8 @@ class Depq
|
|
267
267
|
# returns the priority.
|
268
268
|
def priority
|
269
269
|
if in_queue?
|
270
|
-
|
271
|
-
priority, subpriority =
|
270
|
+
q = depq_or_subpriority()
|
271
|
+
priority, subpriority = q.send(:internal_get_priority, self)
|
272
272
|
priority
|
273
273
|
else
|
274
274
|
index_or_priority()
|
@@ -278,11 +278,11 @@ class Depq
|
|
278
278
|
# returns the subpriority.
|
279
279
|
def subpriority
|
280
280
|
if in_queue?
|
281
|
-
|
282
|
-
priority, subpriority =
|
281
|
+
q = depq_or_subpriority()
|
282
|
+
priority, subpriority = q.send(:internal_get_priority, self)
|
283
283
|
subpriority
|
284
284
|
else
|
285
|
-
|
285
|
+
depq_or_subpriority()
|
286
286
|
end
|
287
287
|
end
|
288
288
|
|
@@ -292,8 +292,8 @@ class Depq
|
|
292
292
|
# So subpriority is not changed if subpriority is not specified or nil for a locator in a queue.
|
293
293
|
# subpriority is set to nil if subpriority is not specified or nil for a locator not in a queue.
|
294
294
|
#
|
295
|
-
#
|
296
|
-
# loc1 =
|
295
|
+
# q = Depq.new
|
296
|
+
# loc1 = q.insert 1, 2, 3
|
297
297
|
# p [loc1.value, loc1.priority, loc1.subpriority] #=> [1, 2, 3]
|
298
298
|
# loc1.update(11, 12)
|
299
299
|
# p [loc1.value, loc1.priority, loc1.subpriority] #=> [11, 12, 3]
|
@@ -308,16 +308,16 @@ class Depq
|
|
308
308
|
def update(value, priority=value, subpriority=nil)
|
309
309
|
subpriority = Integer(subpriority) if subpriority != nil
|
310
310
|
if in_queue?
|
311
|
-
|
311
|
+
q = depq_or_subpriority()
|
312
312
|
if subpriority == nil
|
313
313
|
subpriority = self.subpriority
|
314
314
|
else
|
315
315
|
subpriority = Integer(subpriority)
|
316
316
|
end
|
317
|
-
|
317
|
+
q.send(:internal_set_priority, self, priority, subpriority)
|
318
318
|
else
|
319
319
|
self.index_or_priority = priority
|
320
|
-
self.
|
320
|
+
self.depq_or_subpriority = subpriority
|
321
321
|
end
|
322
322
|
self.value = value
|
323
323
|
nil
|
@@ -327,8 +327,8 @@ class Depq
|
|
327
327
|
#
|
328
328
|
# This method doesn't change the priority and subpriority.
|
329
329
|
#
|
330
|
-
#
|
331
|
-
# loc =
|
330
|
+
# q = Depq.new
|
331
|
+
# loc = q.insert 1, 2, 3
|
332
332
|
# p [loc.value, loc.priority, loc.subpriority] #=> [1, 2, 3]
|
333
333
|
# loc.update_value 10
|
334
334
|
# p [loc.value, loc.priority, loc.subpriority] #=> [10, 2, 3]
|
@@ -341,8 +341,8 @@ class Depq
|
|
341
341
|
#
|
342
342
|
# This method doesn't change the value.
|
343
343
|
#
|
344
|
-
#
|
345
|
-
# loc =
|
344
|
+
# q = Depq.new
|
345
|
+
# loc = q.insert 1, 2, 3
|
346
346
|
# p [loc.value, loc.priority, loc.subpriority] #=> [1, 2, 3]
|
347
347
|
# loc.update_priority 10
|
348
348
|
# p [loc.value, loc.priority, loc.subpriority] #=> [1, 10, 3]
|
@@ -353,10 +353,10 @@ class Depq
|
|
353
353
|
update(self.value, priority, subpriority)
|
354
354
|
end
|
355
355
|
|
356
|
-
def internal_inserted(
|
356
|
+
def internal_inserted(depq, index)
|
357
357
|
raise ArgumentError, "already inserted" if in_queue?
|
358
358
|
priority = index_or_priority()
|
359
|
-
self.
|
359
|
+
self.depq_or_subpriority = depq
|
360
360
|
self.index_or_priority = index
|
361
361
|
priority
|
362
362
|
end
|
@@ -365,7 +365,7 @@ class Depq
|
|
365
365
|
def internal_deleted(priority, subpriority)
|
366
366
|
raise ArgumentError, "not inserted" if !in_queue?
|
367
367
|
self.index_or_priority = priority
|
368
|
-
self.
|
368
|
+
self.depq_or_subpriority = subpriority
|
369
369
|
end
|
370
370
|
private :internal_deleted
|
371
371
|
|
@@ -377,23 +377,23 @@ class Depq
|
|
377
377
|
# It should be a symbol or a Proc which takes two arguments.
|
378
378
|
# If it is omitted, :<=> is used.
|
379
379
|
#
|
380
|
-
#
|
381
|
-
#
|
382
|
-
#
|
383
|
-
# p
|
384
|
-
# p
|
380
|
+
# q = Depq.new
|
381
|
+
# q.insert "Foo"
|
382
|
+
# q.insert "bar"
|
383
|
+
# p q.delete_min #=> "Foo"
|
384
|
+
# p q.delete_min #=> "bar"
|
385
385
|
#
|
386
|
-
#
|
387
|
-
#
|
388
|
-
#
|
389
|
-
# p
|
390
|
-
# p
|
386
|
+
# q = Depq.new(:casecmp)
|
387
|
+
# q.insert "Foo"
|
388
|
+
# q.insert "bar"
|
389
|
+
# p q.delete_min #=> "bar"
|
390
|
+
# p q.delete_min #=> "Foo"
|
391
391
|
#
|
392
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
# p
|
396
|
-
# p
|
392
|
+
# q = Depq.new(lambda {|a,b| a.casecmp(b) })
|
393
|
+
# q.insert "Foo"
|
394
|
+
# q.insert "bar"
|
395
|
+
# p q.delete_min #=> "bar"
|
396
|
+
# p q.delete_min #=> "Foo"
|
397
397
|
#
|
398
398
|
def initialize(cmp = :<=>)
|
399
399
|
@cmp = cmp
|
@@ -486,7 +486,7 @@ class Depq
|
|
486
486
|
private :mode_heapify
|
487
487
|
|
488
488
|
def check_locator(loc)
|
489
|
-
if !self.equal?(loc.
|
489
|
+
if !self.equal?(loc.depq) ||
|
490
490
|
!get_entry(loc.send(:index))[0].equal?(loc)
|
491
491
|
raise ArgumentError, "unexpected locator"
|
492
492
|
end
|
@@ -557,10 +557,10 @@ class Depq
|
|
557
557
|
|
558
558
|
# compare priority1 and priority2.
|
559
559
|
#
|
560
|
-
#
|
561
|
-
# p
|
562
|
-
# p
|
563
|
-
# p
|
560
|
+
# q = Depq.new
|
561
|
+
# p q.compare_priority("a", "b") #=> -1
|
562
|
+
# p q.compare_priority("a", "a") #=> 0
|
563
|
+
# p q.compare_priority("b", "a") #=> 1
|
564
564
|
#
|
565
565
|
def compare_priority(priority1, priority2)
|
566
566
|
if @cmp.kind_of? Symbol
|
@@ -572,12 +572,12 @@ class Depq
|
|
572
572
|
|
573
573
|
# returns true if the queue is empty.
|
574
574
|
#
|
575
|
-
#
|
576
|
-
# p
|
577
|
-
#
|
578
|
-
# p
|
579
|
-
#
|
580
|
-
# p
|
575
|
+
# q = Depq.new
|
576
|
+
# p q.empty? #=> true
|
577
|
+
# q.insert 1
|
578
|
+
# p q.empty? #=> false
|
579
|
+
# q.delete_max
|
580
|
+
# p q.empty? #=> true
|
581
581
|
#
|
582
582
|
def empty?
|
583
583
|
@ary.empty?
|
@@ -585,16 +585,16 @@ class Depq
|
|
585
585
|
|
586
586
|
# returns the number of elements in the queue.
|
587
587
|
#
|
588
|
-
#
|
589
|
-
# p
|
590
|
-
#
|
591
|
-
# p
|
592
|
-
#
|
593
|
-
# p
|
594
|
-
#
|
595
|
-
# p
|
596
|
-
#
|
597
|
-
# p
|
588
|
+
# q = Depq.new
|
589
|
+
# p q.size #=> 0
|
590
|
+
# q.insert 1
|
591
|
+
# p q.size #=> 1
|
592
|
+
# q.insert 1
|
593
|
+
# p q.size #=> 2
|
594
|
+
# q.delete_min
|
595
|
+
# p q.size #=> 1
|
596
|
+
# q.delete_min
|
597
|
+
# p q.size #=> 0
|
598
598
|
#
|
599
599
|
def size
|
600
600
|
@ary.size / ARY_SLICE_SIZE
|
@@ -605,24 +605,24 @@ class Depq
|
|
605
605
|
#
|
606
606
|
# The result is monotonically increased.
|
607
607
|
#
|
608
|
-
#
|
609
|
-
# p [
|
610
|
-
#
|
611
|
-
# p [
|
612
|
-
#
|
613
|
-
# p [
|
614
|
-
#
|
615
|
-
# p [
|
616
|
-
#
|
617
|
-
# p [
|
618
|
-
#
|
619
|
-
# p [
|
620
|
-
#
|
621
|
-
# p [
|
622
|
-
#
|
623
|
-
# p [
|
624
|
-
#
|
625
|
-
# p [
|
608
|
+
# q = Depq.new
|
609
|
+
# p [q.size, q.totalcount] #=> [0, 0]
|
610
|
+
# q.insert 1
|
611
|
+
# p [q.size, q.totalcount] #=> [1, 1]
|
612
|
+
# q.insert 2
|
613
|
+
# p [q.size, q.totalcount] #=> [2, 2]
|
614
|
+
# q.delete_min
|
615
|
+
# p [q.size, q.totalcount] #=> [1, 2]
|
616
|
+
# q.insert 4
|
617
|
+
# p [q.size, q.totalcount] #=> [2, 3]
|
618
|
+
# q.insert 3
|
619
|
+
# p [q.size, q.totalcount] #=> [3, 4]
|
620
|
+
# q.insert 0
|
621
|
+
# p [q.size, q.totalcount] #=> [4, 5]
|
622
|
+
# q.delete_min
|
623
|
+
# p [q.size, q.totalcount] #=> [3, 5]
|
624
|
+
# q.insert 2
|
625
|
+
# p [q.size, q.totalcount] #=> [4, 6]
|
626
626
|
#
|
627
627
|
def totalcount
|
628
628
|
@totalcount
|
@@ -632,15 +632,15 @@ class Depq
|
|
632
632
|
#
|
633
633
|
# Note that totalcount is not changed.
|
634
634
|
#
|
635
|
-
#
|
636
|
-
#
|
637
|
-
#
|
638
|
-
# p
|
639
|
-
# p
|
640
|
-
#
|
641
|
-
# p
|
642
|
-
# p
|
643
|
-
# p
|
635
|
+
# q = Depq.new
|
636
|
+
# q.insert 1
|
637
|
+
# q.insert 1
|
638
|
+
# p q.size #=> 2
|
639
|
+
# p q.totalcount #=> 2
|
640
|
+
# q.clear
|
641
|
+
# p q.size #=> 0
|
642
|
+
# p q.totalcount #=> 2
|
643
|
+
# p q.find_min #=> nil
|
644
644
|
#
|
645
645
|
def clear
|
646
646
|
@ary.clear
|
@@ -661,7 +661,7 @@ class Depq
|
|
661
661
|
set_entry(loc.send(:index), loc, priority, subpriority)
|
662
662
|
else
|
663
663
|
mode_heapify
|
664
|
-
@mode.
|
664
|
+
@mode.update_prio(self, @ary, loc, priority, subpriority)
|
665
665
|
end
|
666
666
|
end
|
667
667
|
private :internal_set_priority
|
@@ -672,10 +672,10 @@ class Depq
|
|
672
672
|
#
|
673
673
|
# The locator should not already be inserted in a queue.
|
674
674
|
#
|
675
|
-
#
|
675
|
+
# q = Depq.new
|
676
676
|
# loc = Depq::Locator.new(1)
|
677
|
-
#
|
678
|
-
# p
|
677
|
+
# q.insert_locator loc
|
678
|
+
# p q.delete_min #=> 1
|
679
679
|
#
|
680
680
|
def insert_locator(loc)
|
681
681
|
subpriority = loc.subpriority || default_subpriority
|
@@ -692,36 +692,36 @@ class Depq
|
|
692
692
|
#
|
693
693
|
# If subpriority is omitted or nil, totalcount is used for stability.
|
694
694
|
#
|
695
|
-
#
|
696
|
-
#
|
697
|
-
#
|
698
|
-
#
|
699
|
-
# p
|
700
|
-
# p
|
701
|
-
# p
|
702
|
-
#
|
703
|
-
#
|
704
|
-
#
|
705
|
-
#
|
706
|
-
#
|
707
|
-
# p
|
708
|
-
# p
|
709
|
-
# p
|
695
|
+
# q = Depq.new
|
696
|
+
# q.insert 3
|
697
|
+
# q.insert 1
|
698
|
+
# q.insert 2
|
699
|
+
# p q.delete_min #=> 1
|
700
|
+
# p q.delete_min #=> 2
|
701
|
+
# p q.delete_min #=> 3
|
702
|
+
#
|
703
|
+
# q = Depq.new
|
704
|
+
# q.insert 3, 10
|
705
|
+
# q.insert 1, 20
|
706
|
+
# q.insert 2, 30
|
707
|
+
# p q.delete_min #=> 3
|
708
|
+
# p q.delete_min #=> 1
|
709
|
+
# p q.delete_min #=> 2
|
710
710
|
#
|
711
711
|
# This method returns a locator which locates the inserted element.
|
712
712
|
# It can be used to update the value and priority, or delete the element.
|
713
713
|
#
|
714
|
-
#
|
715
|
-
#
|
716
|
-
# loc1 =
|
717
|
-
# loc2 =
|
718
|
-
#
|
719
|
-
# p
|
720
|
-
#
|
714
|
+
# q = Depq.new
|
715
|
+
# q.insert 3
|
716
|
+
# loc1 = q.insert 1
|
717
|
+
# loc2 = q.insert 2
|
718
|
+
# q.insert 4
|
719
|
+
# p q.delete_max #=> 4
|
720
|
+
# q.delete_locator loc1
|
721
721
|
# loc2.update 8
|
722
|
-
# p
|
723
|
-
# p
|
724
|
-
# p
|
722
|
+
# p q.delete_max #=> 8
|
723
|
+
# p q.delete_max #=> 3
|
724
|
+
# p q.delete_max #=> nil
|
725
725
|
#
|
726
726
|
def insert(value, priority=value, subpriority=nil)
|
727
727
|
loc = Locator.new(value, priority, subpriority)
|
@@ -739,12 +739,12 @@ class Depq
|
|
739
739
|
#
|
740
740
|
# This method returns nil.
|
741
741
|
#
|
742
|
-
#
|
743
|
-
#
|
744
|
-
# p
|
745
|
-
# p
|
746
|
-
# p
|
747
|
-
# p
|
742
|
+
# q = Depq.new
|
743
|
+
# q.insert_all [3,1,2]
|
744
|
+
# p q.delete_min #=> 1
|
745
|
+
# p q.delete_min #=> 2
|
746
|
+
# p q.delete_min #=> 3
|
747
|
+
# p q.delete_min #=> nil
|
748
748
|
#
|
749
749
|
def insert_all(iter)
|
750
750
|
iter.each {|v|
|
@@ -758,17 +758,17 @@ class Depq
|
|
758
758
|
#
|
759
759
|
# This method doesn't delete the element from the queue.
|
760
760
|
#
|
761
|
-
#
|
762
|
-
# p
|
763
|
-
#
|
764
|
-
#
|
765
|
-
#
|
766
|
-
# p
|
761
|
+
# q = Depq.new
|
762
|
+
# p q.find_min_locator #=> nil
|
763
|
+
# q.insert 3
|
764
|
+
# q.insert 1
|
765
|
+
# q.insert 2
|
766
|
+
# p q.find_min_locator #=> #<Depq::Locator: 1>
|
767
767
|
#
|
768
768
|
def find_min_locator
|
769
769
|
return nil if empty?
|
770
770
|
use_min
|
771
|
-
@mode.
|
771
|
+
@mode.find_min_loc(self, @ary)
|
772
772
|
end
|
773
773
|
|
774
774
|
# return the minimum value with its priority.
|
@@ -776,14 +776,14 @@ class Depq
|
|
776
776
|
#
|
777
777
|
# This method doesn't delete the element from the queue.
|
778
778
|
#
|
779
|
-
#
|
780
|
-
# p
|
781
|
-
#
|
782
|
-
#
|
783
|
-
#
|
784
|
-
# p
|
785
|
-
#
|
786
|
-
# p
|
779
|
+
# q = Depq.new
|
780
|
+
# p q.find_min_priority #=> nil
|
781
|
+
# q.insert "durian", 1
|
782
|
+
# q.insert "banana", 3
|
783
|
+
# q.insert "melon", 2
|
784
|
+
# p q.find_min_priority #=> ["durian", 1]
|
785
|
+
# q.clear
|
786
|
+
# p q.find_min_priority #=> nil
|
787
787
|
#
|
788
788
|
def find_min_priority
|
789
789
|
loc = find_min_locator and [loc.value, loc.priority]
|
@@ -794,12 +794,12 @@ class Depq
|
|
794
794
|
#
|
795
795
|
# This method doesn't delete the element from the queue.
|
796
796
|
#
|
797
|
-
#
|
798
|
-
# p
|
799
|
-
#
|
800
|
-
#
|
801
|
-
#
|
802
|
-
# p
|
797
|
+
# q = Depq.new
|
798
|
+
# p q.find_min #=> nil
|
799
|
+
# q.insert 3
|
800
|
+
# q.insert 1
|
801
|
+
# q.insert 2
|
802
|
+
# p q.find_min #=> 1
|
803
803
|
#
|
804
804
|
def find_min
|
805
805
|
loc = find_min_locator and loc.value
|
@@ -812,17 +812,17 @@ class Depq
|
|
812
812
|
#
|
813
813
|
# This method doesn't delete the element from the queue.
|
814
814
|
#
|
815
|
-
#
|
816
|
-
# p
|
817
|
-
#
|
818
|
-
#
|
819
|
-
#
|
820
|
-
# p
|
815
|
+
# q = Depq.new
|
816
|
+
# p q.find_max_locator #=> nil
|
817
|
+
# q.insert 3
|
818
|
+
# q.insert 1
|
819
|
+
# q.insert 2
|
820
|
+
# p q.find_max_locator #=> #<Depq::Locator: 3>
|
821
821
|
#
|
822
822
|
def find_max_locator
|
823
823
|
return nil if empty?
|
824
824
|
use_max
|
825
|
-
@mode.
|
825
|
+
@mode.find_max_loc(self, @ary)
|
826
826
|
end
|
827
827
|
|
828
828
|
# return the maximum value with its priority.
|
@@ -830,14 +830,14 @@ class Depq
|
|
830
830
|
#
|
831
831
|
# This method doesn't delete the element from the queue.
|
832
832
|
#
|
833
|
-
#
|
834
|
-
# p
|
835
|
-
#
|
836
|
-
#
|
837
|
-
#
|
838
|
-
# p
|
839
|
-
#
|
840
|
-
# p
|
833
|
+
# q = Depq.new
|
834
|
+
# p q.find_max_priority #=> nil
|
835
|
+
# q.insert "durian", 1
|
836
|
+
# q.insert "banana", 3
|
837
|
+
# q.insert "melon", 2
|
838
|
+
# p q.find_max_priority #=> ["banana", 3]
|
839
|
+
# q.clear
|
840
|
+
# p q.find_max_priority #=> nil
|
841
841
|
#
|
842
842
|
def find_max_priority
|
843
843
|
loc = find_max_locator and [loc.value, loc.priority]
|
@@ -848,12 +848,12 @@ class Depq
|
|
848
848
|
#
|
849
849
|
# This method doesn't delete the element from the queue.
|
850
850
|
#
|
851
|
-
#
|
852
|
-
# p
|
853
|
-
#
|
854
|
-
#
|
855
|
-
#
|
856
|
-
# p
|
851
|
+
# q = Depq.new
|
852
|
+
# p q.find_max #=> nil
|
853
|
+
# q.insert 3
|
854
|
+
# q.insert 1
|
855
|
+
# q.insert 2
|
856
|
+
# p q.find_max #=> 3
|
857
857
|
#
|
858
858
|
def find_max
|
859
859
|
loc = find_max_locator and loc.value
|
@@ -864,28 +864,28 @@ class Depq
|
|
864
864
|
# returns the locators for the minimum and maximum element as a two-element array.
|
865
865
|
# If the queue is empty, [nil, nil] is returned.
|
866
866
|
#
|
867
|
-
#
|
868
|
-
# p
|
869
|
-
#
|
870
|
-
#
|
871
|
-
#
|
872
|
-
# p
|
867
|
+
# q = Depq.new
|
868
|
+
# p q.find_minmax_locator #=> [nil, nil]
|
869
|
+
# q.insert 3
|
870
|
+
# q.insert 1
|
871
|
+
# q.insert 2
|
872
|
+
# p q.find_minmax_locator #=> [#<Depq::Locator: 1>, #<Depq::Locator: 3>]
|
873
873
|
#
|
874
874
|
def find_minmax_locator
|
875
875
|
return [nil, nil] if empty?
|
876
876
|
use_minmax
|
877
|
-
return @mode.
|
877
|
+
return @mode.find_minmax_loc(self, @ary)
|
878
878
|
end
|
879
879
|
|
880
880
|
# returns the minimum and maximum value as a two-element array.
|
881
881
|
# If the queue is empty, [nil, nil] is returned.
|
882
882
|
#
|
883
|
-
#
|
884
|
-
# p
|
885
|
-
#
|
886
|
-
#
|
887
|
-
#
|
888
|
-
# p
|
883
|
+
# q = Depq.new
|
884
|
+
# p q.find_minmax #=> [nil, nil]
|
885
|
+
# q.insert 3
|
886
|
+
# q.insert 1
|
887
|
+
# q.insert 2
|
888
|
+
# p q.find_minmax #=> [1, 3]
|
889
889
|
#
|
890
890
|
def find_minmax
|
891
891
|
loc1, loc2 = self.find_minmax_locator
|
@@ -895,14 +895,14 @@ class Depq
|
|
895
895
|
|
896
896
|
# delete the element specified by the locator.
|
897
897
|
#
|
898
|
-
#
|
899
|
-
#
|
900
|
-
# loc =
|
901
|
-
#
|
902
|
-
#
|
903
|
-
# p
|
904
|
-
# p
|
905
|
-
# p
|
898
|
+
# q = Depq.new
|
899
|
+
# q.insert 3
|
900
|
+
# loc = q.insert 2
|
901
|
+
# q.insert 1
|
902
|
+
# q.delete_locator loc
|
903
|
+
# p q.delete_min #=> 1
|
904
|
+
# p q.delete_min #=> 3
|
905
|
+
# p q.delete_min #=> nil
|
906
906
|
#
|
907
907
|
def delete_locator(loc)
|
908
908
|
check_locator(loc)
|
@@ -916,7 +916,7 @@ class Depq
|
|
916
916
|
loc
|
917
917
|
else
|
918
918
|
mode_heapify
|
919
|
-
@heapsize = @mode.
|
919
|
+
@heapsize = @mode.delete_loc(self, @ary, loc)
|
920
920
|
loc
|
921
921
|
end
|
922
922
|
end
|
@@ -926,20 +926,20 @@ class Depq
|
|
926
926
|
# This method returns the locator for the deleted element.
|
927
927
|
# nil is returned if the queue is empty.
|
928
928
|
#
|
929
|
-
#
|
930
|
-
#
|
931
|
-
#
|
932
|
-
#
|
933
|
-
# p
|
934
|
-
# p
|
935
|
-
# p
|
936
|
-
# p
|
929
|
+
# q = Depq.new
|
930
|
+
# q.insert 2
|
931
|
+
# q.insert 1
|
932
|
+
# q.insert 3
|
933
|
+
# p q.delete_min_locator #=> #<Depq::Locator: 1 (no queue)>
|
934
|
+
# p q.delete_min_locator #=> #<Depq::Locator: 2 (no queue)>
|
935
|
+
# p q.delete_min_locator #=> #<Depq::Locator: 3 (no queue)>
|
936
|
+
# p q.delete_min_locator #=> nil
|
937
937
|
#
|
938
938
|
def delete_min_locator
|
939
939
|
return nil if empty?
|
940
940
|
use_min
|
941
|
-
loc = @mode.
|
942
|
-
@heapsize = @mode.
|
941
|
+
loc = @mode.find_min_loc(self, @ary)
|
942
|
+
@heapsize = @mode.delete_loc(self, @ary, loc)
|
943
943
|
loc
|
944
944
|
end
|
945
945
|
|
@@ -949,14 +949,14 @@ class Depq
|
|
949
949
|
# of the deleted element.
|
950
950
|
# nil is returned if the queue is empty.
|
951
951
|
#
|
952
|
-
#
|
953
|
-
#
|
954
|
-
#
|
955
|
-
#
|
956
|
-
# p
|
957
|
-
# p
|
958
|
-
# p
|
959
|
-
# p
|
952
|
+
# q = Depq.new
|
953
|
+
# q.insert "durian", 1
|
954
|
+
# q.insert "banana", 3
|
955
|
+
# q.insert "melon", 2
|
956
|
+
# p q.delete_min_priority #=> ["durian", 1]
|
957
|
+
# p q.delete_min_priority #=> ["melon", 2]
|
958
|
+
# p q.delete_min_priority #=> ["banana", 3]
|
959
|
+
# p q.delete_min_priority #=> nil
|
960
960
|
#
|
961
961
|
def delete_min_priority
|
962
962
|
loc = delete_min_locator
|
@@ -969,14 +969,14 @@ class Depq
|
|
969
969
|
# This method returns the value of the deleted element.
|
970
970
|
# nil is returned if the queue is empty.
|
971
971
|
#
|
972
|
-
#
|
973
|
-
#
|
974
|
-
#
|
975
|
-
#
|
976
|
-
# p
|
977
|
-
# p
|
978
|
-
# p
|
979
|
-
# p
|
972
|
+
# q = Depq.new
|
973
|
+
# q.insert 3
|
974
|
+
# q.insert 1
|
975
|
+
# q.insert 2
|
976
|
+
# p q.delete_min #=> 1
|
977
|
+
# p q.delete_min #=> 2
|
978
|
+
# p q.delete_min #=> 3
|
979
|
+
# p q.delete_min #=> nil
|
980
980
|
#
|
981
981
|
def delete_min
|
982
982
|
loc = delete_min_locator
|
@@ -991,20 +991,20 @@ class Depq
|
|
991
991
|
# This method returns the locator for the deleted element.
|
992
992
|
# nil is returned if the queue is empty.
|
993
993
|
#
|
994
|
-
#
|
995
|
-
#
|
996
|
-
#
|
997
|
-
#
|
998
|
-
# p
|
999
|
-
# p
|
1000
|
-
# p
|
1001
|
-
# p
|
994
|
+
# q = Depq.new
|
995
|
+
# q.insert 2
|
996
|
+
# q.insert 1
|
997
|
+
# q.insert 3
|
998
|
+
# p q.delete_max_locator #=> #<Depq::Locator: 3 (no queue)>
|
999
|
+
# p q.delete_max_locator #=> #<Depq::Locator: 2 (no queue)>
|
1000
|
+
# p q.delete_max_locator #=> #<Depq::Locator: 1 (no queue)>
|
1001
|
+
# p q.delete_max_locator #=> nil
|
1002
1002
|
#
|
1003
1003
|
def delete_max_locator
|
1004
1004
|
return nil if empty?
|
1005
1005
|
use_max
|
1006
|
-
loc = @mode.
|
1007
|
-
@heapsize = @mode.
|
1006
|
+
loc = @mode.find_max_loc(self, @ary)
|
1007
|
+
@heapsize = @mode.delete_loc(self, @ary, loc)
|
1008
1008
|
loc
|
1009
1009
|
end
|
1010
1010
|
|
@@ -1014,14 +1014,14 @@ class Depq
|
|
1014
1014
|
# of the deleted element.
|
1015
1015
|
# nil is returned if the queue is empty.
|
1016
1016
|
#
|
1017
|
-
#
|
1018
|
-
#
|
1019
|
-
#
|
1020
|
-
#
|
1021
|
-
# p
|
1022
|
-
# p
|
1023
|
-
# p
|
1024
|
-
# p
|
1017
|
+
# q = Depq.new
|
1018
|
+
# q.insert "durian", 1
|
1019
|
+
# q.insert "banana", 3
|
1020
|
+
# q.insert "melon", 2
|
1021
|
+
# p q.delete_max_priority #=> ["banana", 3]
|
1022
|
+
# p q.delete_max_priority #=> ["melon", 2]
|
1023
|
+
# p q.delete_max_priority #=> ["durian", 1]
|
1024
|
+
# p q.delete_max_priority #=> nil
|
1025
1025
|
#
|
1026
1026
|
def delete_max_priority
|
1027
1027
|
loc = delete_max_locator
|
@@ -1034,14 +1034,14 @@ class Depq
|
|
1034
1034
|
# This method returns the value of the deleted element.
|
1035
1035
|
# nil is returned if the queue is empty.
|
1036
1036
|
#
|
1037
|
-
#
|
1038
|
-
#
|
1039
|
-
#
|
1040
|
-
#
|
1041
|
-
# p
|
1042
|
-
# p
|
1043
|
-
# p
|
1044
|
-
# p
|
1037
|
+
# q = Depq.new
|
1038
|
+
# q.insert 3
|
1039
|
+
# q.insert 1
|
1040
|
+
# q.insert 2
|
1041
|
+
# p q.delete_max #=> 3
|
1042
|
+
# p q.delete_max #=> 2
|
1043
|
+
# p q.delete_max #=> 1
|
1044
|
+
# p q.delete_max #=> nil
|
1045
1045
|
#
|
1046
1046
|
def delete_max
|
1047
1047
|
loc = delete_max_locator
|
@@ -1055,14 +1055,14 @@ class Depq
|
|
1055
1055
|
# This method returns the locator for the deleted element.
|
1056
1056
|
# nil is returned if the queue is empty.
|
1057
1057
|
#
|
1058
|
-
#
|
1059
|
-
#
|
1060
|
-
#
|
1061
|
-
#
|
1062
|
-
# p
|
1063
|
-
# p
|
1064
|
-
# p
|
1065
|
-
# p
|
1058
|
+
# q = Depq.new
|
1059
|
+
# q.insert 1
|
1060
|
+
# q.insert 4
|
1061
|
+
# q.insert 3
|
1062
|
+
# p q.delete_unspecified_locator #=> #<Depq::Locator: 3 (no queue)>
|
1063
|
+
# p q.delete_unspecified_locator #=> #<Depq::Locator: 4 (no queue)>
|
1064
|
+
# p q.delete_unspecified_locator #=> #<Depq::Locator: 1 (no queue)>
|
1065
|
+
# p q.delete_unspecified_locator #=> nil
|
1066
1066
|
#
|
1067
1067
|
def delete_unspecified_locator
|
1068
1068
|
return nil if empty?
|
@@ -1077,14 +1077,14 @@ class Depq
|
|
1077
1077
|
# of the deleted element.
|
1078
1078
|
# nil is returned if the queue is empty.
|
1079
1079
|
#
|
1080
|
-
#
|
1081
|
-
#
|
1082
|
-
#
|
1083
|
-
#
|
1084
|
-
# p
|
1085
|
-
# p
|
1086
|
-
# p
|
1087
|
-
# p
|
1080
|
+
# q = Depq.new
|
1081
|
+
# q.insert "durian", 1
|
1082
|
+
# q.insert "banana", 3
|
1083
|
+
# q.insert "melon", 2
|
1084
|
+
# p q.delete_unspecified_priority #=> ["melon", 2]
|
1085
|
+
# p q.delete_unspecified_priority #=> ["banana", 3]
|
1086
|
+
# p q.delete_unspecified_priority #=> ["durian", 1]
|
1087
|
+
# p q.delete_unspecified_priority #=> nil
|
1088
1088
|
#
|
1089
1089
|
def delete_unspecified_priority
|
1090
1090
|
loc = delete_unspecified_locator
|
@@ -1098,14 +1098,14 @@ class Depq
|
|
1098
1098
|
# This method returns the value of the deleted element.
|
1099
1099
|
# nil is returned if the queue is empty.
|
1100
1100
|
#
|
1101
|
-
#
|
1102
|
-
#
|
1103
|
-
#
|
1104
|
-
#
|
1105
|
-
# p
|
1106
|
-
# p
|
1107
|
-
# p
|
1108
|
-
# p
|
1101
|
+
# q = Depq.new
|
1102
|
+
# q.insert 1
|
1103
|
+
# q.insert 4
|
1104
|
+
# q.insert 3
|
1105
|
+
# p q.delete_unspecified #=> 3
|
1106
|
+
# p q.delete_unspecified #=> 4
|
1107
|
+
# p q.delete_unspecified #=> 1
|
1108
|
+
# p q.delete_unspecified #=> nil
|
1109
1109
|
#
|
1110
1110
|
def delete_unspecified
|
1111
1111
|
loc = delete_unspecified_locator
|
@@ -1117,12 +1117,12 @@ class Depq
|
|
1117
1117
|
#
|
1118
1118
|
# The iteration order is unspecified.
|
1119
1119
|
#
|
1120
|
-
#
|
1121
|
-
#
|
1122
|
-
#
|
1123
|
-
#
|
1124
|
-
# p
|
1125
|
-
#
|
1120
|
+
# q = Depq.new
|
1121
|
+
# q.insert 3
|
1122
|
+
# q.insert 1
|
1123
|
+
# q.insert 2
|
1124
|
+
# p q.delete_min #=> 1
|
1125
|
+
# q.each_locator {|v|
|
1126
1126
|
# p v #=> #<Depq::Locator: 2>, #<Depq::Locator: 3>
|
1127
1127
|
# }
|
1128
1128
|
#
|
@@ -1135,11 +1135,11 @@ class Depq
|
|
1135
1135
|
|
1136
1136
|
# iterate over the values and priorities in the queue.
|
1137
1137
|
#
|
1138
|
-
#
|
1139
|
-
#
|
1140
|
-
#
|
1141
|
-
#
|
1142
|
-
#
|
1138
|
+
# q = Depq.new
|
1139
|
+
# q.insert "durian", 1
|
1140
|
+
# q.insert "banana", 3
|
1141
|
+
# q.insert "melon", 2
|
1142
|
+
# q.each_with_priority {|val, priority|
|
1143
1143
|
# p [val, priority]
|
1144
1144
|
# }
|
1145
1145
|
# #=> ["durian", 1]
|
@@ -1157,12 +1157,12 @@ class Depq
|
|
1157
1157
|
#
|
1158
1158
|
# The iteration order is unspecified.
|
1159
1159
|
#
|
1160
|
-
#
|
1161
|
-
#
|
1162
|
-
#
|
1163
|
-
#
|
1164
|
-
# p
|
1165
|
-
#
|
1160
|
+
# q = Depq.new
|
1161
|
+
# q.insert 3
|
1162
|
+
# q.insert 1
|
1163
|
+
# q.insert 2
|
1164
|
+
# p q.delete_min #=> 1
|
1165
|
+
# q.each {|v|
|
1166
1166
|
# p v #=> 2, 3
|
1167
1167
|
# }
|
1168
1168
|
#
|
@@ -1182,32 +1182,32 @@ class Depq
|
|
1182
1182
|
def Depq.nlargest(n, iter)
|
1183
1183
|
limit = (n * Math.log(1+n)).ceil
|
1184
1184
|
limit = 1024 if limit < 1024
|
1185
|
-
|
1185
|
+
q = Depq.new
|
1186
1186
|
threshold = nil
|
1187
1187
|
iter.each {|v|
|
1188
|
-
if
|
1189
|
-
if
|
1188
|
+
if q.size < n
|
1189
|
+
if q.size == 0
|
1190
1190
|
threshold = v
|
1191
1191
|
else
|
1192
1192
|
threshold = v if (v <=> threshold) < 0
|
1193
1193
|
end
|
1194
|
-
|
1194
|
+
q.insert v
|
1195
1195
|
else
|
1196
1196
|
if (v <=> threshold) > 0
|
1197
|
-
|
1198
|
-
if limit <
|
1197
|
+
q.insert v
|
1198
|
+
if limit < q.size
|
1199
1199
|
tmp = []
|
1200
|
-
n.times { tmp <<
|
1201
|
-
|
1202
|
-
|
1200
|
+
n.times { tmp << q.delete_max }
|
1201
|
+
q.clear
|
1202
|
+
q.insert_all tmp
|
1203
1203
|
threshold = tmp.last
|
1204
1204
|
end
|
1205
1205
|
end
|
1206
1206
|
end
|
1207
1207
|
}
|
1208
|
-
n =
|
1208
|
+
n = q.size if q.size < n
|
1209
1209
|
a = []
|
1210
|
-
n.times { a <<
|
1210
|
+
n.times { a << q.delete_max }
|
1211
1211
|
a.reverse!
|
1212
1212
|
a
|
1213
1213
|
end
|
@@ -1221,33 +1221,33 @@ class Depq
|
|
1221
1221
|
def Depq.nsmallest(n, iter)
|
1222
1222
|
limit = (n * Math.log(1+n)).ceil
|
1223
1223
|
limit = 1024 if limit < 1024
|
1224
|
-
|
1224
|
+
q = Depq.new
|
1225
1225
|
threshold = nil
|
1226
1226
|
iter.each {|v|
|
1227
|
-
if
|
1228
|
-
if
|
1227
|
+
if q.size < n
|
1228
|
+
if q.size == 0
|
1229
1229
|
threshold = v
|
1230
1230
|
else
|
1231
1231
|
threshold = v if (v <=> threshold) > 0
|
1232
1232
|
end
|
1233
|
-
|
1233
|
+
q.insert v
|
1234
1234
|
else
|
1235
1235
|
if (v <=> threshold) < 0
|
1236
|
-
|
1237
|
-
if limit <
|
1236
|
+
q.insert v
|
1237
|
+
if limit < q.size
|
1238
1238
|
tmp = []
|
1239
|
-
n.times { tmp <<
|
1240
|
-
|
1241
|
-
|
1239
|
+
n.times { tmp << q.delete_min }
|
1240
|
+
q.clear
|
1241
|
+
q.insert_all tmp
|
1242
1242
|
threshold = tmp.last
|
1243
1243
|
end
|
1244
1244
|
end
|
1245
1245
|
end
|
1246
1246
|
}
|
1247
|
-
n =
|
1247
|
+
n = q.size if q.size < n
|
1248
1248
|
a = []
|
1249
1249
|
n.times {
|
1250
|
-
a <<
|
1250
|
+
a << q.delete_min
|
1251
1251
|
}
|
1252
1252
|
a
|
1253
1253
|
end
|
@@ -1268,7 +1268,7 @@ class Depq
|
|
1268
1268
|
# # 6
|
1269
1269
|
#
|
1270
1270
|
def Depq.merge(*iters, &b)
|
1271
|
-
|
1271
|
+
q = Depq.new
|
1272
1272
|
iters.each {|enum|
|
1273
1273
|
enum = enum.to_enum unless enum.kind_of? Enumerator
|
1274
1274
|
begin
|
@@ -1276,18 +1276,18 @@ class Depq
|
|
1276
1276
|
rescue StopIteration
|
1277
1277
|
next
|
1278
1278
|
end
|
1279
|
-
|
1279
|
+
q.insert enum, val
|
1280
1280
|
}
|
1281
1281
|
loop = lambda {|y, meth|
|
1282
|
-
until
|
1283
|
-
loc =
|
1282
|
+
until q.empty?
|
1283
|
+
loc = q.find_min_locator
|
1284
1284
|
enum = loc.value
|
1285
1285
|
val = loc.priority
|
1286
1286
|
y.send meth, val
|
1287
1287
|
begin
|
1288
1288
|
val = enum.next
|
1289
1289
|
rescue StopIteration
|
1290
|
-
|
1290
|
+
q.delete_locator loc
|
1291
1291
|
next
|
1292
1292
|
end
|
1293
1293
|
loc.update enum, val
|
@@ -1330,15 +1330,6 @@ class Depq
|
|
1330
1330
|
[locator, priority, subpriority]
|
1331
1331
|
end
|
1332
1332
|
|
1333
|
-
def each_entry(ary)
|
1334
|
-
0.upto(self.size-1) {|i|
|
1335
|
-
ei = ary[i*ARY_SLICE_SIZE+0]
|
1336
|
-
pi = ary[i*ARY_SLICE_SIZE+1]
|
1337
|
-
si = ary[i*ARY_SLICE_SIZE+2]
|
1338
|
-
yield ei, pi, si
|
1339
|
-
}
|
1340
|
-
end
|
1341
|
-
|
1342
1333
|
def swap(ary, i, j)
|
1343
1334
|
ei, pi, si = get_entry(ary, i)
|
1344
1335
|
ej, pj, sj = get_entry(ary, j)
|
@@ -1352,40 +1343,40 @@ class Depq
|
|
1352
1343
|
module SimpleHeap
|
1353
1344
|
include HeapArray
|
1354
1345
|
|
1355
|
-
def upheap(
|
1346
|
+
def upheap(q, ary, j)
|
1356
1347
|
while true
|
1357
1348
|
return if j <= 0
|
1358
1349
|
i = (j-1) >> 1
|
1359
|
-
return if upper?(
|
1350
|
+
return if upper?(q, ary, i, j)
|
1360
1351
|
swap(ary, j, i)
|
1361
1352
|
j = i
|
1362
1353
|
end
|
1363
1354
|
end
|
1364
1355
|
|
1365
|
-
def downheap(
|
1356
|
+
def downheap(q, ary, i)
|
1366
1357
|
while true
|
1367
1358
|
j = i*2+1
|
1368
1359
|
k = i*2+2
|
1369
1360
|
return if size(ary) <= j
|
1370
1361
|
if size(ary) == k
|
1371
|
-
return if upper?(
|
1362
|
+
return if upper?(q, ary, i, j)
|
1372
1363
|
swap(ary, i, j)
|
1373
1364
|
i = j
|
1374
1365
|
else
|
1375
|
-
return if upper?(
|
1376
|
-
loc = upper?(
|
1366
|
+
return if upper?(q, ary, i, j) && upper?(q, ary, i, k)
|
1367
|
+
loc = upper?(q, ary, j, k) ? j : k
|
1377
1368
|
swap(ary, i, loc)
|
1378
1369
|
i = loc
|
1379
1370
|
end
|
1380
1371
|
end
|
1381
1372
|
end
|
1382
1373
|
|
1383
|
-
def
|
1374
|
+
def find_top_loc(q, ary)
|
1384
1375
|
loc, _ = get_entry(ary, 0)
|
1385
1376
|
loc
|
1386
1377
|
end
|
1387
1378
|
|
1388
|
-
def
|
1379
|
+
def delete_loc(q, ary, loc)
|
1389
1380
|
i = loc.send(:index)
|
1390
1381
|
_, priority, subpriority = get_entry(ary, i)
|
1391
1382
|
last = size(ary) - 1
|
@@ -1394,12 +1385,12 @@ class Depq
|
|
1394
1385
|
if i != last
|
1395
1386
|
set_entry(ary, i, el, pl, sl)
|
1396
1387
|
el.send(:index=, i)
|
1397
|
-
downheap(
|
1388
|
+
downheap(q, ary, i)
|
1398
1389
|
end
|
1399
1390
|
size(ary)
|
1400
1391
|
end
|
1401
1392
|
|
1402
|
-
def heapify(
|
1393
|
+
def heapify(q, ary, heapsize=0)
|
1403
1394
|
# compare number of data movements in worst case.
|
1404
1395
|
# choose a way for less data movements.
|
1405
1396
|
#
|
@@ -1435,11 +1426,11 @@ class Depq
|
|
1435
1426
|
if currentsize - 1 < (h - 1) * (currentsize - heapsize + 1)
|
1436
1427
|
n = (currentsize - 2) / 2
|
1437
1428
|
n.downto(0) {|i|
|
1438
|
-
downheap(
|
1429
|
+
downheap(q, ary, i)
|
1439
1430
|
}
|
1440
1431
|
else
|
1441
1432
|
heapsize.upto(currentsize-1) {|i|
|
1442
|
-
upheap(
|
1433
|
+
upheap(q, ary, i)
|
1443
1434
|
}
|
1444
1435
|
end
|
1445
1436
|
currentsize
|
@@ -1451,27 +1442,27 @@ class Depq
|
|
1451
1442
|
class << MinHeap
|
1452
1443
|
include SimpleHeap
|
1453
1444
|
|
1454
|
-
def upper?(
|
1445
|
+
def upper?(q, ary, i, j)
|
1455
1446
|
ei, pi, si = get_entry(ary, i)
|
1456
1447
|
ej, pj, sj = get_entry(ary, j)
|
1457
|
-
|
1448
|
+
q.send(:compare_for_min, pi, si, pj, sj) <= 0
|
1458
1449
|
end
|
1459
1450
|
|
1460
|
-
def
|
1451
|
+
def update_prio(q, ary, loc, priority, subpriority)
|
1461
1452
|
i = loc.send(:index)
|
1462
1453
|
ei, pi, si = get_entry(ary, i)
|
1463
|
-
cmp =
|
1454
|
+
cmp = q.send(:compare_for_min, pi, si, priority, subpriority)
|
1464
1455
|
set_entry(ary, i, ei, priority, subpriority)
|
1465
1456
|
if cmp < 0
|
1466
1457
|
# loc.priority < priority
|
1467
|
-
downheap(
|
1458
|
+
downheap(q, ary, i)
|
1468
1459
|
elsif cmp > 0
|
1469
1460
|
# loc.priority > priority
|
1470
|
-
upheap(
|
1461
|
+
upheap(q, ary, i)
|
1471
1462
|
end
|
1472
1463
|
end
|
1473
1464
|
|
1474
|
-
alias
|
1465
|
+
alias find_min_loc find_top_loc
|
1475
1466
|
end
|
1476
1467
|
|
1477
1468
|
module MaxHeap
|
@@ -1479,28 +1470,28 @@ class Depq
|
|
1479
1470
|
class << MaxHeap
|
1480
1471
|
include SimpleHeap
|
1481
1472
|
|
1482
|
-
def upper?(
|
1473
|
+
def upper?(q, ary, i, j)
|
1483
1474
|
ei, pi, si = get_entry(ary, i)
|
1484
1475
|
ej, pj, sj = get_entry(ary, j)
|
1485
|
-
|
1476
|
+
q.send(:compare_for_max, pi, si, pj, sj) >= 0
|
1486
1477
|
end
|
1487
1478
|
|
1488
|
-
def
|
1479
|
+
def update_prio(q, ary, loc, priority, subpriority)
|
1489
1480
|
i = loc.send(:index)
|
1490
1481
|
ei, pi, si = get_entry(ary, i)
|
1491
1482
|
subpriority ||= si
|
1492
|
-
cmp =
|
1483
|
+
cmp = q.send(:compare_for_max, pi, si, priority, subpriority)
|
1493
1484
|
set_entry(ary, i, ei, priority, subpriority)
|
1494
1485
|
if cmp < 0
|
1495
1486
|
# loc.priority < priority
|
1496
|
-
upheap(
|
1487
|
+
upheap(q, ary, i)
|
1497
1488
|
elsif cmp > 0
|
1498
1489
|
# loc.priority > priority
|
1499
|
-
downheap(
|
1490
|
+
downheap(q, ary, i)
|
1500
1491
|
end
|
1501
1492
|
end
|
1502
1493
|
|
1503
|
-
alias
|
1494
|
+
alias find_max_loc find_top_loc
|
1504
1495
|
end
|
1505
1496
|
|
1506
1497
|
module IntervalHeap
|
@@ -1520,23 +1511,23 @@ class Depq
|
|
1520
1511
|
def child2_minside(i) i &= ~1; (i*2+4) & ~1 end
|
1521
1512
|
def child2_maxside(i) i &= ~1; (i*2+4) | 1 end
|
1522
1513
|
|
1523
|
-
def pcmp(
|
1514
|
+
def pcmp(q, ary, i, j)
|
1524
1515
|
ei, pi, si = get_entry(ary, i)
|
1525
1516
|
ej, pj, sj = get_entry(ary, j)
|
1526
|
-
|
1517
|
+
q.compare_priority(pi, pj)
|
1527
1518
|
end
|
1528
1519
|
|
1529
|
-
def scmp(
|
1520
|
+
def scmp(q, ary, i, j)
|
1530
1521
|
ei, pi, si = get_entry(ary, i)
|
1531
1522
|
ej, pj, sj = get_entry(ary, j)
|
1532
1523
|
si <=> sj
|
1533
1524
|
end
|
1534
1525
|
|
1535
|
-
def psame(
|
1536
|
-
pcmp(
|
1526
|
+
def psame(q, ary, i)
|
1527
|
+
pcmp(q, ary, minside(i), maxside(i)) == 0
|
1537
1528
|
end
|
1538
1529
|
|
1539
|
-
def travel(
|
1530
|
+
def travel(q, ary, i, range, fix_subpriority)
|
1540
1531
|
while true
|
1541
1532
|
j = yield i
|
1542
1533
|
return i if !j
|
@@ -1545,7 +1536,7 @@ class Depq
|
|
1545
1536
|
imin = minside(i)
|
1546
1537
|
imax = maxside(i)
|
1547
1538
|
if range.include?(imin) && range.include?(imax)
|
1548
|
-
if pcmp(
|
1539
|
+
if pcmp(q, ary, imin, imax) == 0 && scmp(q, ary, imin, imax) > 0
|
1549
1540
|
swap ary, imin, imax
|
1550
1541
|
end
|
1551
1542
|
end
|
@@ -1554,15 +1545,15 @@ class Depq
|
|
1554
1545
|
end
|
1555
1546
|
end
|
1556
1547
|
|
1557
|
-
def upheap_minside(
|
1558
|
-
travel(
|
1548
|
+
def upheap_minside(q, ary, i, range)
|
1549
|
+
travel(q, ary, i, range, true) {|j|
|
1559
1550
|
if root?(j)
|
1560
1551
|
nil
|
1561
1552
|
elsif !range.include?(k = parent_minside(j))
|
1562
1553
|
nil
|
1563
1554
|
else
|
1564
|
-
if pcmp(
|
1565
|
-
swap(ary, minside(k), maxside(k)) if psame(
|
1555
|
+
if pcmp(q, ary, k, j) > 0
|
1556
|
+
swap(ary, minside(k), maxside(k)) if psame(q, ary, k)
|
1566
1557
|
k
|
1567
1558
|
else
|
1568
1559
|
nil
|
@@ -1571,14 +1562,14 @@ class Depq
|
|
1571
1562
|
}
|
1572
1563
|
end
|
1573
1564
|
|
1574
|
-
def upheap_maxside(
|
1575
|
-
travel(
|
1565
|
+
def upheap_maxside(q, ary, i, range)
|
1566
|
+
travel(q, ary, i, range, true) {|j|
|
1576
1567
|
if root?(j)
|
1577
1568
|
nil
|
1578
1569
|
elsif !range.include?(k = parent_maxside(j))
|
1579
1570
|
nil
|
1580
1571
|
else
|
1581
|
-
if pcmp(
|
1572
|
+
if pcmp(q, ary, k, j) < 0
|
1582
1573
|
k
|
1583
1574
|
else
|
1584
1575
|
nil
|
@@ -1587,8 +1578,8 @@ class Depq
|
|
1587
1578
|
}
|
1588
1579
|
end
|
1589
1580
|
|
1590
|
-
def downheap_minside(
|
1591
|
-
travel(
|
1581
|
+
def downheap_minside(q, ary, i, range)
|
1582
|
+
travel(q, ary, i, range, true) {|j|
|
1592
1583
|
k1 = child1_minside(j)
|
1593
1584
|
k2 = child2_minside(j)
|
1594
1585
|
if !range.include?(k1)
|
@@ -1597,17 +1588,17 @@ class Depq
|
|
1597
1588
|
if !range.include?(k2)
|
1598
1589
|
k = k1
|
1599
1590
|
else
|
1600
|
-
if (pc = pcmp(
|
1591
|
+
if (pc = pcmp(q, ary, k1, k2)) < 0
|
1601
1592
|
k = k1
|
1602
1593
|
elsif pc > 0
|
1603
1594
|
k = k2
|
1604
|
-
elsif (sc = scmp(
|
1595
|
+
elsif (sc = scmp(q, ary, k1, k2)) <= 0
|
1605
1596
|
k = k1
|
1606
1597
|
else
|
1607
1598
|
k = k2
|
1608
1599
|
end
|
1609
1600
|
end
|
1610
|
-
if (pc = pcmp(
|
1601
|
+
if (pc = pcmp(q, ary, k, j)) < 0
|
1611
1602
|
k
|
1612
1603
|
else
|
1613
1604
|
nil
|
@@ -1616,29 +1607,29 @@ class Depq
|
|
1616
1607
|
}
|
1617
1608
|
end
|
1618
1609
|
|
1619
|
-
def downheap_maxside(
|
1620
|
-
travel(
|
1610
|
+
def downheap_maxside(q, ary, i, range)
|
1611
|
+
travel(q, ary, i, range, true) {|j|
|
1621
1612
|
k1 = child1_maxside(j)
|
1622
1613
|
k2 = child2_maxside(j)
|
1623
|
-
k1 = minside(k1) if range.include?(k1) && psame(
|
1624
|
-
k2 = minside(k2) if range.include?(k2) && psame(
|
1614
|
+
k1 = minside(k1) if range.include?(k1) && psame(q, ary, k1)
|
1615
|
+
k2 = minside(k2) if range.include?(k2) && psame(q, ary, k2)
|
1625
1616
|
if !range.include?(k1)
|
1626
1617
|
nil
|
1627
1618
|
else
|
1628
1619
|
if !range.include?(k2)
|
1629
1620
|
k = k1
|
1630
1621
|
else
|
1631
|
-
if (pc = pcmp(
|
1622
|
+
if (pc = pcmp(q, ary, k1, k2)) < 0
|
1632
1623
|
k = k2
|
1633
1624
|
elsif pc > 0
|
1634
1625
|
k = k1
|
1635
|
-
elsif (sc = scmp(
|
1626
|
+
elsif (sc = scmp(q, ary, k1, k2)) <= 0
|
1636
1627
|
k = k1
|
1637
1628
|
else
|
1638
1629
|
k = k2
|
1639
1630
|
end
|
1640
1631
|
end
|
1641
|
-
if (pc = pcmp(
|
1632
|
+
if (pc = pcmp(q, ary, k, j)) > 0
|
1642
1633
|
swap(ary, minside(k), maxside(k)) if minside?(k)
|
1643
1634
|
maxside(k)
|
1644
1635
|
else
|
@@ -1648,27 +1639,25 @@ class Depq
|
|
1648
1639
|
}
|
1649
1640
|
end
|
1650
1641
|
|
1651
|
-
def upheap_sub(
|
1652
|
-
travel(
|
1642
|
+
def upheap_sub(q, ary, i, range)
|
1643
|
+
travel(q, ary, i, range, false) {|j|
|
1653
1644
|
k = nil
|
1654
1645
|
if minside?(j)
|
1655
|
-
if range.include?(kk=parent_maxside(j)) && pcmp(
|
1646
|
+
if range.include?(kk=parent_maxside(j)) && pcmp(q, ary, j, kk) == 0
|
1656
1647
|
k = kk
|
1657
|
-
elsif range.include?(kk=parent_minside(j)) && pcmp(
|
1648
|
+
elsif range.include?(kk=parent_minside(j)) && pcmp(q, ary, j, kk) == 0
|
1658
1649
|
k = kk
|
1659
1650
|
end
|
1660
1651
|
else
|
1661
|
-
if range.include?(kk=minside(j)) && pcmp(
|
1652
|
+
if range.include?(kk=minside(j)) && pcmp(q, ary, j, kk) == 0
|
1662
1653
|
k = kk
|
1663
|
-
elsif range.include?(kk=parent_maxside(j)) && pcmp(
|
1654
|
+
elsif range.include?(kk=parent_maxside(j)) && pcmp(q, ary, j, kk) == 0
|
1664
1655
|
k = kk
|
1665
1656
|
end
|
1666
1657
|
end
|
1667
1658
|
if !k
|
1668
1659
|
nil
|
1669
|
-
elsif
|
1670
|
-
nil
|
1671
|
-
elsif scmp(pd, ary, k, j) > 0
|
1660
|
+
elsif scmp(q, ary, k, j) > 0
|
1672
1661
|
k
|
1673
1662
|
else
|
1674
1663
|
nil
|
@@ -1676,34 +1665,34 @@ class Depq
|
|
1676
1665
|
}
|
1677
1666
|
end
|
1678
1667
|
|
1679
|
-
def downheap_sub(
|
1680
|
-
travel(
|
1668
|
+
def downheap_sub(q, ary, i, range)
|
1669
|
+
travel(q, ary, i, range, false) {|j|
|
1681
1670
|
k1 = k2 = nil
|
1682
1671
|
if minside?(j)
|
1683
|
-
if range.include?(kk=maxside(j)) && pcmp(
|
1672
|
+
if range.include?(kk=maxside(j)) && pcmp(q, ary, j, kk) == 0
|
1684
1673
|
k1 = kk
|
1685
1674
|
else
|
1686
|
-
k1 = kk if range.include?(kk=child1_minside(j)) && pcmp(
|
1687
|
-
k2 = kk if range.include?(kk=child2_minside(j)) && pcmp(
|
1675
|
+
k1 = kk if range.include?(kk=child1_minside(j)) && pcmp(q, ary, j, kk) == 0
|
1676
|
+
k2 = kk if range.include?(kk=child2_minside(j)) && pcmp(q, ary, j, kk) == 0
|
1688
1677
|
end
|
1689
1678
|
else
|
1690
|
-
if range.include?(kk=child1_minside(j)) && pcmp(
|
1679
|
+
if range.include?(kk=child1_minside(j)) && pcmp(q, ary, j, kk) == 0
|
1691
1680
|
k1 = kk
|
1692
|
-
elsif range.include?(kk=child1_maxside(j)) && pcmp(
|
1681
|
+
elsif range.include?(kk=child1_maxside(j)) && pcmp(q, ary, j, kk) == 0
|
1693
1682
|
k1 = kk
|
1694
1683
|
end
|
1695
|
-
if range.include?(kk=child2_minside(j)) && pcmp(
|
1684
|
+
if range.include?(kk=child2_minside(j)) && pcmp(q, ary, j, kk) == 0
|
1696
1685
|
k2 = kk
|
1697
|
-
elsif range.include?(kk=child2_maxside(j)) && pcmp(
|
1686
|
+
elsif range.include?(kk=child2_maxside(j)) && pcmp(q, ary, j, kk) == 0
|
1698
1687
|
k2 = kk
|
1699
1688
|
end
|
1700
1689
|
end
|
1701
1690
|
if k1 && k2
|
1702
|
-
k = scmp(
|
1691
|
+
k = scmp(q, ary, k1, k2) > 0 ? k2 : k1
|
1703
1692
|
else
|
1704
1693
|
k = k1 || k2
|
1705
1694
|
end
|
1706
|
-
if k && scmp(
|
1695
|
+
if k && scmp(q, ary, k, j) < 0
|
1707
1696
|
k
|
1708
1697
|
else
|
1709
1698
|
nil
|
@@ -1711,73 +1700,66 @@ class Depq
|
|
1711
1700
|
}
|
1712
1701
|
end
|
1713
1702
|
|
1714
|
-
def adjust(
|
1703
|
+
def adjust(q, ary, i, range)
|
1715
1704
|
if minside?(i)
|
1716
|
-
j = upheap_minside(
|
1705
|
+
j = upheap_minside(q, ary, i, range)
|
1717
1706
|
if i == j
|
1718
|
-
i = downheap_minside(
|
1719
|
-
if !range.include?(child1_minside(i)) && range.include?(j=maxside(i)) && pcmp(
|
1707
|
+
i = downheap_minside(q, ary, i, range)
|
1708
|
+
if !range.include?(child1_minside(i)) && range.include?(j=maxside(i)) && pcmp(q, ary, i, j) > 0
|
1720
1709
|
swap(ary, i, j)
|
1721
1710
|
i = j
|
1722
1711
|
end
|
1723
1712
|
if maxside?(i) || !range.include?(maxside(i))
|
1724
|
-
i = upheap_maxside(
|
1713
|
+
i = upheap_maxside(q, ary, i, range)
|
1725
1714
|
end
|
1726
1715
|
end
|
1727
1716
|
else
|
1728
|
-
j = upheap_maxside(
|
1717
|
+
j = upheap_maxside(q, ary, i, range)
|
1729
1718
|
if i == j
|
1730
|
-
i = downheap_maxside(
|
1719
|
+
i = downheap_maxside(q, ary, i, range)
|
1731
1720
|
if !range.include?(child1_maxside(i))
|
1732
|
-
if range.include?(j=child1_minside(i)) && pcmp(
|
1721
|
+
if range.include?(j=child1_minside(i)) && pcmp(q, ary, j, i) > 0
|
1733
1722
|
swap(ary, i, j)
|
1734
1723
|
i = j
|
1735
|
-
elsif range.include?(j=minside(i)) && pcmp(
|
1724
|
+
elsif range.include?(j=minside(i)) && pcmp(q, ary, j, i) > 0
|
1736
1725
|
swap(ary, i, j)
|
1737
1726
|
i = j
|
1738
1727
|
end
|
1739
1728
|
end
|
1740
1729
|
if minside?(i)
|
1741
|
-
i = upheap_minside(
|
1730
|
+
i = upheap_minside(q, ary, i, range)
|
1742
1731
|
end
|
1743
1732
|
end
|
1744
1733
|
end
|
1745
|
-
i = upheap_sub(
|
1746
|
-
downheap_sub(
|
1734
|
+
i = upheap_sub(q, ary, i, range)
|
1735
|
+
downheap_sub(q, ary, i, range)
|
1747
1736
|
end
|
1748
1737
|
|
1749
|
-
def
|
1738
|
+
def update_prio(q, ary, loc, prio, subprio)
|
1750
1739
|
i = loc.send(:index)
|
1751
1740
|
ei, pi, si = get_entry(ary, i)
|
1752
1741
|
subpriority ||= si
|
1753
1742
|
set_entry(ary, i, ei, prio, subprio)
|
1754
1743
|
range = 0...size(ary)
|
1755
|
-
adjust(
|
1756
|
-
end
|
1757
|
-
|
1758
|
-
def insert_internal(pd, ary, loc, prio, subprio)
|
1759
|
-
i = size(ary)
|
1760
|
-
set_entry(ary, i, loc, prio, subprio)
|
1761
|
-
range = 0...size(ary)
|
1762
|
-
adjust(pd, ary, i, range)
|
1744
|
+
adjust(q, ary, i, range)
|
1763
1745
|
end
|
1764
1746
|
|
1765
|
-
def heapify(
|
1747
|
+
def heapify(q, ary, heapsize=0)
|
1766
1748
|
currentsize = size(ary)
|
1767
1749
|
h = Math.log(currentsize+1)/Math.log(2)
|
1768
1750
|
if currentsize - 1 < (h - 1) * (currentsize - heapsize + 1)
|
1769
1751
|
(currentsize-1).downto(0) {|i|
|
1770
|
-
adjust(
|
1752
|
+
adjust(q, ary, i, i...currentsize)
|
1771
1753
|
}
|
1772
1754
|
else
|
1773
1755
|
heapsize.upto(currentsize-1) {|i|
|
1774
|
-
adjust(
|
1756
|
+
adjust(q, ary, i, 0...(i+1))
|
1775
1757
|
}
|
1776
1758
|
end
|
1777
1759
|
currentsize
|
1778
1760
|
end
|
1779
1761
|
|
1780
|
-
def
|
1762
|
+
def find_minmax_loc(q, ary)
|
1781
1763
|
case size(ary)
|
1782
1764
|
when 0
|
1783
1765
|
[nil, nil]
|
@@ -1785,7 +1767,7 @@ class Depq
|
|
1785
1767
|
e0, p0, s0 = get_entry(ary, 0)
|
1786
1768
|
[e0, e0]
|
1787
1769
|
else
|
1788
|
-
if pcmp(
|
1770
|
+
if pcmp(q, ary, 0, 1) == 0
|
1789
1771
|
e0, p0, s0 = get_entry(ary, 0)
|
1790
1772
|
[e0, e0]
|
1791
1773
|
else
|
@@ -1796,15 +1778,15 @@ class Depq
|
|
1796
1778
|
end
|
1797
1779
|
end
|
1798
1780
|
|
1799
|
-
def
|
1800
|
-
|
1781
|
+
def find_min_loc(q, ary)
|
1782
|
+
find_minmax_loc(q, ary).first
|
1801
1783
|
end
|
1802
1784
|
|
1803
|
-
def
|
1804
|
-
|
1785
|
+
def find_max_loc(q, ary)
|
1786
|
+
find_minmax_loc(q, ary).last
|
1805
1787
|
end
|
1806
1788
|
|
1807
|
-
def
|
1789
|
+
def delete_loc(q, ary, loc)
|
1808
1790
|
i = loc.send(:index)
|
1809
1791
|
_, priority, subpriority = get_entry(ary, i)
|
1810
1792
|
last = size(ary) - 1
|
@@ -1813,7 +1795,7 @@ class Depq
|
|
1813
1795
|
if i != last
|
1814
1796
|
set_entry(ary, i, el, pl, sl)
|
1815
1797
|
el.send(:index=, i)
|
1816
|
-
adjust(
|
1798
|
+
adjust(q, ary, i, 0...last)
|
1817
1799
|
end
|
1818
1800
|
size(ary)
|
1819
1801
|
end
|