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