pqueue 1.0.0 → 2.0.0
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/.ruby +58 -0
- data/COPYING.rdoc +31 -0
- data/HISTORY.rdoc +28 -0
- data/README.rdoc +57 -0
- data/lib/pqueue.rb +198 -150
- data/lib/pqueue/legacy.rb +269 -0
- data/test/test_pqueue.rb +37 -20
- metadata +80 -70
- data/HISTORY +0 -11
- data/LICENSE +0 -167
- data/MANIFEST +0 -21
- data/README +0 -44
- data/RELEASE +0 -10
- data/meta/abstract +0 -4
- data/meta/authors +0 -6
- data/meta/created +0 -1
- data/meta/homepage +0 -1
- data/meta/license +0 -1
- data/meta/package +0 -1
- data/meta/project +0 -1
- data/meta/released +0 -1
- data/meta/repository +0 -1
- data/meta/summary +0 -1
- data/meta/title +0 -1
- data/meta/version +0 -1
data/.ruby
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- meta
|
4
|
+
authors:
|
5
|
+
- name: K. Kodama
|
6
|
+
- name: Ronald Butler
|
7
|
+
- name: Olivier Renaud
|
8
|
+
- name: Rick Bradley
|
9
|
+
- name: Thomas Sawyer
|
10
|
+
email: transfire@gmail.com
|
11
|
+
copyrights:
|
12
|
+
- holder: K. Kodama
|
13
|
+
year: '2001'
|
14
|
+
replacements: []
|
15
|
+
alternatives: []
|
16
|
+
requirements:
|
17
|
+
- name: detroit
|
18
|
+
groups:
|
19
|
+
- build
|
20
|
+
development: true
|
21
|
+
- name: microtest
|
22
|
+
groups:
|
23
|
+
- test
|
24
|
+
development: true
|
25
|
+
- name: ae
|
26
|
+
groups:
|
27
|
+
- test
|
28
|
+
development: true
|
29
|
+
dependencies: []
|
30
|
+
conflicts: []
|
31
|
+
repositories:
|
32
|
+
- uri: git://github.com/rubyworks/pqueue.git
|
33
|
+
scm: git
|
34
|
+
name: upstream
|
35
|
+
resources:
|
36
|
+
home: http://rubyworks.github.com/pqueue
|
37
|
+
code: http://github.com/rubyworks/pqueue
|
38
|
+
mail: http://groups.google.com/group/rubyworks-mailinglist
|
39
|
+
bugs: http://github.com/rubyworks/pqueue/issues
|
40
|
+
extra: {}
|
41
|
+
load_path:
|
42
|
+
- lib
|
43
|
+
revision: 0
|
44
|
+
created: '2001-03-10'
|
45
|
+
summary: Queue of Prioritized Elements
|
46
|
+
title: PQueue
|
47
|
+
version: 2.0.0
|
48
|
+
name: pqueue
|
49
|
+
description: ! 'A priority queue is like a standard queue, except that each inserted
|
50
|
+
elements
|
51
|
+
|
52
|
+
is given a certain priority, based on the result of the comparison block given
|
53
|
+
|
54
|
+
at instantiation time. Retrieving an element from the queue will always return
|
55
|
+
|
56
|
+
the one with the highest priority.'
|
57
|
+
organization: rubyworks
|
58
|
+
date: '2011-10-29'
|
data/COPYING.rdoc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
= COPYRIGHT NOTICES
|
2
|
+
|
3
|
+
== PQueue
|
4
|
+
|
5
|
+
Copyright:: (c) 2011 Rubyworks
|
6
|
+
License:: BSD-2-Clause
|
7
|
+
Website:: http://rubyworks.github.com/pqueue
|
8
|
+
|
9
|
+
Copyright 2011 Rubyworks. All rights reserved.
|
10
|
+
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
13
|
+
|
14
|
+
1. Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
|
17
|
+
2. Redistributions in binary form must reproduce the above copyright
|
18
|
+
notice, this list of conditions and the following disclaimer in the
|
19
|
+
documentation and/or other materials provided with the distribution.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
22
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
23
|
+
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
24
|
+
COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
25
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
26
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
28
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
29
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
30
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
|
data/HISTORY.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= CHANGE HISTORY
|
2
|
+
|
3
|
+
== 2.0.0 / 2011-10-29
|
4
|
+
|
5
|
+
This is a complete rewrite to simplify the design and use more
|
6
|
+
of Ruby's internal methods. Overall performance should be markedly
|
7
|
+
improved. A few method names have changed to be more consistent with
|
8
|
+
Ruby's other data structure. Note that the internal heap is now in reverse
|
9
|
+
order from the previous version. If using #to_a be aware that the priority
|
10
|
+
order will be reversed. This release also switches the library to
|
11
|
+
distribution under the BSD-2-Clause license.
|
12
|
+
|
13
|
+
Changes:
|
14
|
+
|
15
|
+
* Rewrite library.
|
16
|
+
* Modernize build configuration.
|
17
|
+
* Switch to BSD-2-Clause license.
|
18
|
+
|
19
|
+
|
20
|
+
== 1.0.0 / 2009-07-05
|
21
|
+
|
22
|
+
This is the initial standalone release of PQueue, spun-off from the
|
23
|
+
Ruby Facets and originally written by K. Komada.
|
24
|
+
|
25
|
+
Changes:
|
26
|
+
|
27
|
+
* Happy New Birthday!
|
28
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= PQueue
|
2
|
+
|
3
|
+
{Home}[http://rubyworks.github.com/pqueue] |
|
4
|
+
{Code}[http://github.com/rubyworks/pqueue] |
|
5
|
+
{Docs}[http://rubydoc.info/gems/pqueue/frames] |
|
6
|
+
{Mail}[http://groups.google.com/group/rubyworks] | #rubyworks
|
7
|
+
|
8
|
+
{<img src="http://travis-ci.org/rubyworks/pqueue.png" />}[http://travis-ci.org/rubyworks/pqueue]
|
9
|
+
|
10
|
+
== DESCRIPTION
|
11
|
+
|
12
|
+
Priority queue with array based heap.
|
13
|
+
|
14
|
+
A priority queue is like a standard queue, except that each inserted
|
15
|
+
elements is given a certain priority, based on the result of the
|
16
|
+
comparison block given at instantiation time. Also, retrieving an element
|
17
|
+
from the queue will always return the one with the highest priority
|
18
|
+
(see #pop and #top).
|
19
|
+
|
20
|
+
The default is to compare the elements in respect to their #<=> method.
|
21
|
+
For example, Numeric elements with higher values will have higher
|
22
|
+
priorities.
|
23
|
+
|
24
|
+
This library is a rewrite of the original PQueue.rb by K. Kodama and
|
25
|
+
Heap.rb by Ronald Butler. The two libraries were later merged
|
26
|
+
and generally improved by Olivier Renaud. Then the whole library
|
27
|
+
rewritten by Trans using the original as a functional reference.
|
28
|
+
|
29
|
+
|
30
|
+
== SYNOPSIS
|
31
|
+
|
32
|
+
require 'pqueue'
|
33
|
+
|
34
|
+
pq = PQueue.new([2,3,1]){ |a,b| a > b }
|
35
|
+
|
36
|
+
pq.pop #=> 3
|
37
|
+
|
38
|
+
|
39
|
+
== ACKNOWLEDGMENTS
|
40
|
+
|
41
|
+
Although the library has been completely rewritten since, we still would
|
42
|
+
like to acknowledge the efforts of the original PQueue authors and
|
43
|
+
contributors.
|
44
|
+
|
45
|
+
* Olivier Renaud (2007)
|
46
|
+
* Rick Bradley (2003)
|
47
|
+
* Ronald Butler (2002)
|
48
|
+
* K Kodama (2001, original library)
|
49
|
+
|
50
|
+
|
51
|
+
== COPYRIGHTS
|
52
|
+
|
53
|
+
Copyright (c) 2011 Rubyworks
|
54
|
+
|
55
|
+
PQueue is distributable in accordance with the *FreeBSD* license.
|
56
|
+
|
57
|
+
See the COPYING.rdoc file for details.
|
data/lib/pqueue.rb
CHANGED
@@ -6,147 +6,128 @@
|
|
6
6
|
# from the queue will always return the one with the highest priority
|
7
7
|
# (see #pop and #top).
|
8
8
|
#
|
9
|
-
# The default is to compare the elements in repect to their
|
9
|
+
# The default is to compare the elements in repect to their #<=> method.
|
10
10
|
# For example, Numeric elements with higher values will have higher
|
11
11
|
# priorities.
|
12
12
|
#
|
13
|
+
# Note that as of version 2.0 the internal queue is kept in the reverse order
|
14
|
+
# from how it was kept in previous version. If you had used #to_a in the
|
15
|
+
# past then be sure to adjust for the priorities to be ordered back-to-front
|
16
|
+
# instead of the oterh way around.
|
17
|
+
#
|
13
18
|
class PQueue
|
14
19
|
|
15
|
-
#
|
16
|
-
|
17
|
-
# compare Proc
|
18
|
-
attr_reader :gt
|
19
|
-
attr_reader :qarray #:nodoc:
|
20
|
-
protected :qarray
|
20
|
+
#
|
21
|
+
VERSION = "2.0.0" #:erb: VERSION = "<%= version %>"
|
21
22
|
|
23
|
+
#
|
22
24
|
# Returns a new priority queue.
|
23
25
|
#
|
24
26
|
# If elements are given, build the priority queue with these initial
|
25
27
|
# values. The elements object must respond to #to_a.
|
26
28
|
#
|
27
29
|
# If a block is given, it will be used to determine the priority between
|
28
|
-
# the elements.
|
30
|
+
# the elements. The block must must take two arguments and return `1`, `0`,
|
31
|
+
# or `-1` or `true`, `nil` or `false. It should return `0` or `nil` if the
|
32
|
+
# two arguments are considered equal, return `1` or `true` if the first
|
33
|
+
# argument is considered greater than the later, and `-1` or `false` if
|
34
|
+
# the later is considred to be greater than the first.
|
29
35
|
#
|
30
36
|
# By default, the priority queue retrieves maximum elements first
|
31
|
-
#
|
37
|
+
# using the #<=> method.
|
38
|
+
#
|
32
39
|
def initialize(elements=nil, &block) # :yields: a, b
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@gt = block || lambda {|a,b| a > b}
|
40
|
+
@que = []
|
41
|
+
@cmp = block || lambda{ |a,b| a <=> b }
|
36
42
|
replace(elements) if elements
|
37
43
|
end
|
38
44
|
|
39
|
-
|
45
|
+
protected
|
40
46
|
|
41
|
-
# Assumes that the tree is a heap, for nodes < k.
|
42
47
|
#
|
43
|
-
# The
|
44
|
-
|
45
|
-
|
46
|
-
v = @qarray[k]
|
47
|
-
while k2 > 0 && @gt[v, @qarray[k2]]
|
48
|
-
@qarray[k] = @qarray[k2]
|
49
|
-
k = k2
|
50
|
-
k2 = k2.div(2)
|
51
|
-
end
|
52
|
-
@qarray[k] = v
|
53
|
-
end
|
48
|
+
# The underlying heap.
|
49
|
+
#
|
50
|
+
attr_reader :que #:nodoc:
|
54
51
|
|
55
|
-
|
56
|
-
#
|
57
|
-
# The element at index k will go down until it finds its place.
|
58
|
-
def downheap(k)
|
59
|
-
v = @qarray[k]
|
60
|
-
q2 = @size.div(2)
|
61
|
-
loop {
|
62
|
-
break if k > q2
|
63
|
-
j = 2 * k
|
64
|
-
if j < @size && @gt[@qarray[j+1], @qarray[j]]
|
65
|
-
j += 1
|
66
|
-
end
|
67
|
-
break if @gt[v, @qarray[j]]
|
68
|
-
@qarray[k] = @qarray[j]
|
69
|
-
k = j
|
70
|
-
}
|
71
|
-
@qarray[k] = v;
|
72
|
-
end
|
52
|
+
public
|
73
53
|
|
54
|
+
#
|
55
|
+
# Priority comparison procedure.
|
56
|
+
#
|
57
|
+
attr_reader :cmp
|
74
58
|
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
# def h(t)
|
81
|
-
# l = 2 * t
|
82
|
-
# r = l + 1
|
83
|
-
# hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
|
84
|
-
# if @gt[@qarray[hi],@qarray[t]]
|
85
|
-
# @qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
|
86
|
-
# h(hi) if hi <= @size.div(2)
|
87
|
-
# end
|
88
|
-
# end
|
89
|
-
|
90
|
-
# Make a heap out of an unordered array.
|
91
|
-
def heapify
|
92
|
-
@size.div(2).downto(1) do |t|
|
93
|
-
begin
|
94
|
-
l = 2 * t
|
95
|
-
r = l + 1
|
96
|
-
hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
|
97
|
-
if @gt[@qarray[hi],@qarray[t]]
|
98
|
-
@qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
|
99
|
-
if hi <= @size.div(2)
|
100
|
-
t = hi
|
101
|
-
redo
|
102
|
-
end # if
|
103
|
-
end #if
|
104
|
-
end #begin
|
105
|
-
end # downto
|
59
|
+
#
|
60
|
+
# Returns the size of the queue.
|
61
|
+
#
|
62
|
+
def size
|
63
|
+
@que.size
|
106
64
|
end
|
107
65
|
|
108
|
-
|
66
|
+
#
|
67
|
+
# Alias of size.
|
68
|
+
#
|
69
|
+
alias length size
|
109
70
|
|
71
|
+
#
|
110
72
|
# Add an element in the priority queue.
|
111
73
|
#
|
112
|
-
# The insertion time is O(log n), with n the size of the queue.
|
113
74
|
def push(v)
|
114
|
-
@
|
115
|
-
@
|
116
|
-
|
117
|
-
return self
|
75
|
+
@que << v
|
76
|
+
reheap(@que.size-1)
|
77
|
+
self
|
118
78
|
end
|
119
79
|
|
80
|
+
#
|
81
|
+
# Alias of #push.
|
82
|
+
#
|
120
83
|
alias :<< :push
|
121
84
|
|
85
|
+
#
|
86
|
+
# Alias of #push.
|
87
|
+
#
|
88
|
+
alias enq push
|
89
|
+
|
90
|
+
#
|
122
91
|
# Return the element with the highest priority and remove it from
|
123
92
|
# the queue.
|
124
93
|
#
|
125
|
-
# The highest priority is determined by the block given at
|
94
|
+
# The highest priority is determined by the block given at instantiation
|
126
95
|
# time.
|
127
96
|
#
|
128
|
-
# The deletion time is O(log n), with n the size of the queue.
|
97
|
+
# The deletion time is O(log n), with n is the size of the queue.
|
129
98
|
#
|
130
99
|
# Return nil if the queue is empty.
|
100
|
+
#
|
131
101
|
def pop
|
132
102
|
return nil if empty?
|
133
|
-
|
134
|
-
@qarray[1] = @qarray[@size]
|
135
|
-
@size -= 1
|
136
|
-
downheap(1)
|
137
|
-
return res
|
103
|
+
@que.pop
|
138
104
|
end
|
139
105
|
|
140
|
-
#
|
106
|
+
#
|
107
|
+
# Alias of #push.
|
108
|
+
#
|
109
|
+
alias shift push
|
110
|
+
|
111
|
+
#
|
112
|
+
# Alias of #pop.
|
113
|
+
#
|
114
|
+
alias deq push
|
115
|
+
|
116
|
+
#
|
117
|
+
# Returns the element with the highest priority, but
|
118
|
+
# does not remove it from the queue.
|
119
|
+
#
|
141
120
|
def top
|
142
121
|
return nil if empty?
|
143
|
-
return @
|
122
|
+
return @que.last
|
144
123
|
end
|
145
124
|
|
125
|
+
#
|
146
126
|
# Add more than one element at the same time. See #push.
|
147
127
|
#
|
148
|
-
# The elements object must respond to #to_a, or
|
149
|
-
|
128
|
+
# The elements object must respond to #to_a, or be a PQueue itself.
|
129
|
+
#
|
130
|
+
def concat(elements)
|
150
131
|
if empty?
|
151
132
|
if elements.kind_of?(PQueue)
|
152
133
|
initialize_copy(elements)
|
@@ -155,115 +136,182 @@ class PQueue
|
|
155
136
|
end
|
156
137
|
else
|
157
138
|
if elements.kind_of?(PQueue)
|
158
|
-
@
|
159
|
-
|
139
|
+
@que.concat(elements.que)
|
140
|
+
sort!
|
160
141
|
else
|
161
|
-
|
162
|
-
|
163
|
-
ary.size.times{ @size += 1; upheap(@size)}
|
142
|
+
@que.concat(elements.to_a)
|
143
|
+
sort!
|
164
144
|
end
|
165
145
|
end
|
166
146
|
return self
|
167
147
|
end
|
168
148
|
|
169
|
-
|
170
|
-
|
149
|
+
#
|
150
|
+
# Alias for #concat.
|
151
|
+
#
|
152
|
+
alias :merge! :concat
|
171
153
|
|
154
|
+
#
|
172
155
|
# Return top n-element as a sorted array.
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
156
|
+
#
|
157
|
+
def take(n=@size)
|
158
|
+
a = []
|
159
|
+
n.times{a.push(pop)}
|
160
|
+
a
|
177
161
|
end
|
178
162
|
|
179
|
-
|
180
|
-
#
|
163
|
+
#
|
164
|
+
# Returns true if there is no more elements left in the queue.
|
165
|
+
#
|
181
166
|
def empty?
|
182
|
-
|
167
|
+
@que.empty?
|
183
168
|
end
|
184
169
|
|
170
|
+
#
|
185
171
|
# Remove all elements from the priority queue.
|
172
|
+
#
|
186
173
|
def clear
|
187
|
-
@
|
188
|
-
|
189
|
-
return self
|
174
|
+
@que.clear
|
175
|
+
self
|
190
176
|
end
|
191
177
|
|
178
|
+
#
|
192
179
|
# Replace the content of the heap by the new elements.
|
193
180
|
#
|
194
|
-
# The elements object must respond to #to_a, or to be
|
181
|
+
# The elements object must respond to #to_a, or to be
|
182
|
+
# a PQueue itself.
|
183
|
+
#
|
195
184
|
def replace(elements)
|
196
185
|
if elements.kind_of?(PQueue)
|
197
186
|
initialize_copy(elements)
|
198
187
|
else
|
199
|
-
@
|
200
|
-
|
201
|
-
heapify
|
188
|
+
@que.replace(elements.to_a)
|
189
|
+
sort!
|
202
190
|
end
|
203
|
-
|
191
|
+
self
|
204
192
|
end
|
205
193
|
|
194
|
+
#
|
206
195
|
# Return a sorted array, with highest priority first.
|
196
|
+
#
|
207
197
|
def to_a
|
208
|
-
|
209
|
-
old_size = @size
|
210
|
-
res = pop_array
|
211
|
-
@qarray = old_qarray
|
212
|
-
@size = old_size
|
213
|
-
return res
|
198
|
+
@que.dup
|
214
199
|
end
|
215
200
|
|
216
|
-
alias :sort :to_a
|
217
|
-
|
218
|
-
# Replace the top element with the given one, and return this top element.
|
219
201
|
#
|
220
|
-
# Equivalent to successively calling #pop and #push(v).
|
221
|
-
def replace_top(v)
|
222
|
-
# replace top element
|
223
|
-
if empty?
|
224
|
-
@qarray[1] = v
|
225
|
-
@size += 1
|
226
|
-
return nil
|
227
|
-
else
|
228
|
-
res = @qarray[1]
|
229
|
-
@qarray[1] = v
|
230
|
-
downheap(1)
|
231
|
-
return res
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
202
|
# Return true if the given object is present in the queue.
|
203
|
+
#
|
236
204
|
def include?(element)
|
237
|
-
|
205
|
+
@que.include?(element)
|
206
|
+
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# Push element onto queue while popping off and returning the next element.
|
210
|
+
# This is qquivalent to successively calling #pop and #push(v).
|
211
|
+
#
|
212
|
+
def swap(v)
|
213
|
+
r = pop
|
214
|
+
push(v)
|
215
|
+
r
|
238
216
|
end
|
239
217
|
|
218
|
+
#
|
240
219
|
# Iterate over the ordered elements, destructively.
|
220
|
+
#
|
241
221
|
def each_pop #:yields: popped
|
242
222
|
until empty?
|
243
223
|
yield pop
|
244
224
|
end
|
245
|
-
|
225
|
+
nil
|
246
226
|
end
|
247
227
|
|
248
|
-
#
|
228
|
+
#
|
229
|
+
# Pretty inspection string.
|
230
|
+
#
|
249
231
|
def inspect
|
250
|
-
"<#{self.class}: size=#{
|
232
|
+
"<#{self.class}: size=#{size}, top=#{top || "nil"}>"
|
251
233
|
end
|
252
234
|
|
253
|
-
|
254
|
-
### Override Object methods
|
255
|
-
|
235
|
+
#
|
256
236
|
# Return true if the queues contain equal elements.
|
237
|
+
#
|
257
238
|
def ==(other)
|
258
|
-
|
239
|
+
size == other.size && to_a == other.to_a
|
259
240
|
end
|
260
241
|
|
261
|
-
|
242
|
+
private
|
262
243
|
|
244
|
+
#
|
245
|
+
#
|
246
|
+
#
|
263
247
|
def initialize_copy(other)
|
264
|
-
@
|
265
|
-
@
|
266
|
-
|
248
|
+
@cmp = other.cmp
|
249
|
+
@que = other.que.dup
|
250
|
+
sort!
|
267
251
|
end
|
268
|
-
end # class PQueue
|
269
252
|
|
253
|
+
#
|
254
|
+
# The element at index k will be repositioned to its proper place.
|
255
|
+
#
|
256
|
+
# This, of course, assumes the queue is already sorted.
|
257
|
+
#
|
258
|
+
def reheap(k)
|
259
|
+
return self if size <= 1
|
260
|
+
|
261
|
+
que = @que.dup
|
262
|
+
|
263
|
+
v = que.delete_at(k)
|
264
|
+
|
265
|
+
i = que.size.div(2)
|
266
|
+
q = i
|
267
|
+
r = nil
|
268
|
+
|
269
|
+
loop do
|
270
|
+
case @cmp.call(v, que[i])
|
271
|
+
when 0, nil
|
272
|
+
r = i
|
273
|
+
break
|
274
|
+
when 1, true
|
275
|
+
i = (que.size + i).div(2)
|
276
|
+
i += 1 if i == q # don't repeat yourself
|
277
|
+
when -1, false
|
278
|
+
i = (i).div(2)
|
279
|
+
i -= 1 if i == q # don't repeat yourself
|
280
|
+
else
|
281
|
+
warn "bad comparison procedure in #{self.inspect}"
|
282
|
+
r = i
|
283
|
+
break
|
284
|
+
end
|
285
|
+
q = i
|
286
|
+
end
|
287
|
+
|
288
|
+
que.insert(r, v)
|
289
|
+
|
290
|
+
@que = que
|
291
|
+
|
292
|
+
return self
|
293
|
+
end
|
294
|
+
|
295
|
+
#
|
296
|
+
# Sort the queue in accorance to the given comparison procedure.
|
297
|
+
#
|
298
|
+
def sort!
|
299
|
+
@que.sort! do |a,b|
|
300
|
+
case @cmp.call(a,b)
|
301
|
+
when 0, nil then 0
|
302
|
+
when 1, true then 1
|
303
|
+
when -1, false then -1
|
304
|
+
else
|
305
|
+
warn "bad comparison procedure in #{self.inspect}"
|
306
|
+
0
|
307
|
+
end
|
308
|
+
end
|
309
|
+
self
|
310
|
+
end
|
311
|
+
|
312
|
+
#
|
313
|
+
# Alias of #sort!
|
314
|
+
#
|
315
|
+
alias heapify sort!
|
316
|
+
|
317
|
+
end # class PQueue
|