1 | =head1 NAME |
1 | =head1 NAME |
2 | |
2 | |
3 | Array::Heap - treat perl arrays as heaps (priority queues) |
3 | Array::Heap - treat perl arrays as binary heaps/priority queues |
4 | |
4 | |
5 | =head1 SYNOPSIS |
5 | =head1 SYNOPSIS |
6 | |
6 | |
7 | use Array::Heap; |
7 | use Array::Heap; |
8 | |
8 | |
… | |
… | |
10 | |
10 | |
11 | There are a multitude of heap and heap-like modules on CPAN, you might |
11 | There are a multitude of heap and heap-like modules on CPAN, you might |
12 | want to search for /Heap/ and /Priority/ to find many. They implement more |
12 | want to search for /Heap/ and /Priority/ to find many. They implement more |
13 | or less fancy datastructures that might well be what you are looking for. |
13 | or less fancy datastructures that might well be what you are looking for. |
14 | |
14 | |
15 | This module takes a different approach: It exports functions (i.e. not |
15 | This module takes a different approach: It exports functions (i.e. no |
16 | object orientation) that are loosely modeled after the C++ STL's heap |
16 | object orientation) that are loosely modeled after the C++ STL's binary |
17 | functions. They all take an array as argument, just like perl's built-in |
17 | heap functions. They all take an array as argument, just like perl's |
18 | functions C<push>, C<pop> etc. |
18 | built-in functions C<push>, C<pop> etc. |
19 | |
19 | |
20 | The implementation itself is in C for maximum speed (although I doubt it |
20 | The implementation itself is in C for maximum speed. |
21 | makes that much of a difference). |
|
|
22 | |
21 | |
23 | =head1 FUNCTIONS |
22 | =head1 FUNCTIONS |
24 | |
23 | |
25 | All of the following functions are being exported by default. |
24 | All of the following functions are being exported by default. |
26 | |
25 | |
… | |
… | |
29 | =cut |
28 | =cut |
30 | |
29 | |
31 | package Array::Heap; |
30 | package Array::Heap; |
32 | |
31 | |
33 | BEGIN { |
32 | BEGIN { |
34 | $VERSION = "1.2"; |
33 | $VERSION = 3.22; |
35 | |
34 | |
36 | require XSLoader; |
35 | require XSLoader; |
37 | XSLoader::load Array::Heap, $VERSION; |
36 | XSLoader::load ("Array::Heap", $VERSION); |
38 | } |
37 | } |
39 | |
38 | |
40 | use base Exporter; |
39 | use base Exporter; |
41 | |
40 | |
42 | @EXPORT = qw(make_heap make_heap_lex make_heap_cmp push_heap push_heap_lex push_heap_cmp pop_heap pop_heap_lex pop_heap_cmp); |
41 | @EXPORT = qw( |
|
|
42 | make_heap make_heap_lex make_heap_cmp make_heap_idx |
|
|
43 | push_heap push_heap_lex push_heap_cmp push_heap_idx |
|
|
44 | pop_heap pop_heap_lex pop_heap_cmp pop_heap_idx |
|
|
45 | splice_heap splice_heap_lex splice_heap_cmp splice_heap_idx |
|
|
46 | adjust_heap adjust_heap_lex adjust_heap_cmp adjust_heap_idx |
|
|
47 | ); |
43 | |
48 | |
44 | =item make_heap @heap (\@) |
49 | =item make_heap @heap (\@) |
45 | |
50 | |
46 | Reorders the elements in the array so they form a heap, with the lowest |
51 | Reorders the elements in the array so they form a heap, with the lowest |
47 | value "on top" of the heap (corresponding to the first array element). |
52 | value "on top" of the heap (corresponding to the first array element). |
48 | |
53 | |
|
|
54 | =item make_heap_idx @heap (\@) |
|
|
55 | |
|
|
56 | Just like C<make_heap>, but updates the index (see INDEXED OPERATIONS). |
|
|
57 | |
49 | =item make_heap_lex @heap (\@) |
58 | =item make_heap_lex @heap (\@) |
50 | |
59 | |
51 | Just like C<make_heap>, but in string comparison order instead of numerical |
60 | Just like C<make_heap>, but in string comparison order instead of numerical |
52 | comparison order. |
61 | comparison order. |
53 | |
62 | |
… | |
… | |
57 | |
66 | |
58 | =item push_heap @heap, $element, ... (\@@) |
67 | =item push_heap @heap, $element, ... (\@@) |
59 | |
68 | |
60 | Adds the given element(s) to the heap. |
69 | Adds the given element(s) to the heap. |
61 | |
70 | |
|
|
71 | =item push_heap_idx @heap, $element, ... (\@@) |
|
|
72 | |
|
|
73 | Just like C<push_heap>, but updates the index (see INDEXED OPERATIONS). |
|
|
74 | |
62 | =item push_heap_lex @heap, $element, ... (\@@) |
75 | =item push_heap_lex @heap, $element, ... (\@@) |
63 | |
76 | |
64 | Just like C<push_heap>, but in string comparison order instead of numerical |
77 | Just like C<push_heap>, but in string comparison order instead of numerical |
65 | comparison order. |
78 | comparison order. |
66 | |
79 | |
… | |
… | |
70 | |
83 | |
71 | =item pop_heap @heap (\@) |
84 | =item pop_heap @heap (\@) |
72 | |
85 | |
73 | Removes the topmost (lowest) heap element and repairs the heap. |
86 | Removes the topmost (lowest) heap element and repairs the heap. |
74 | |
87 | |
|
|
88 | =item pop_heap_idx @heap (\@) |
|
|
89 | |
|
|
90 | Just like C<pop_heap>, but updates the index (see INDEXED OPERATIONS). |
|
|
91 | |
75 | =item pop_heap_lex @heap (\@) |
92 | =item pop_heap_lex @heap (\@) |
76 | |
93 | |
77 | Just like C<pop_heap>, but in string comparison order instead of numerical |
94 | Just like C<pop_heap>, but in string comparison order instead of numerical |
78 | comparison order. |
95 | comparison order. |
79 | |
96 | |
80 | =item pop_heap_cmp { compare } @heap (&\@) |
97 | =item pop_heap_cmp { compare } @heap (&\@) |
81 | |
98 | |
82 | Just like C<pop_heap>, but takes a custom comparison function. |
99 | Just like C<pop_heap>, but takes a custom comparison function. |
|
|
100 | |
|
|
101 | =item splice_heap @heap, $index (\@$) |
|
|
102 | |
|
|
103 | Similar to C<pop_heap>, but removes and returns the element at index |
|
|
104 | C<$index>. |
|
|
105 | |
|
|
106 | =item splice_heap_idx @heap, $index (\@$) |
|
|
107 | |
|
|
108 | Just like C<splice_heap>, but updates the index (see INDEXED OPERATIONS). |
|
|
109 | |
|
|
110 | =item splice_heap_lex @heap, $index (\@$) |
|
|
111 | |
|
|
112 | Just like C<splice_heap>, but in string comparison order instead of |
|
|
113 | numerical comparison order. |
|
|
114 | |
|
|
115 | =item splice_heap_cmp { compare } @heap, $index (&\@$) |
|
|
116 | |
|
|
117 | Just like C<splice_heap>, but takes a custom comparison function. |
|
|
118 | |
|
|
119 | =item adjust_heap @heap, $index (\@$) |
|
|
120 | |
|
|
121 | Assuming you have only changed the element at index C<$index>, repair the |
|
|
122 | heap again. Can be used to remove elements, replace elements, adjust the |
|
|
123 | priority of elements and more. |
|
|
124 | |
|
|
125 | =item adjust_heap_idx @heap, $index (\@$) |
|
|
126 | |
|
|
127 | Just like C<adjust_heap>, but updates the index (see INDEXED OPERATIONS). |
|
|
128 | |
|
|
129 | =item adjust_heap_lex @heap, $index (\@$) |
|
|
130 | |
|
|
131 | Just like C<adjust_heap>, but in string comparison order instead of |
|
|
132 | numerical comparison order. |
|
|
133 | |
|
|
134 | =item adjust_heap_cmp { compare } @heap, $index (&\@$) |
|
|
135 | |
|
|
136 | Just like C<adjust_heap>, but takes a custom comparison function. |
83 | |
137 | |
84 | =cut |
138 | =cut |
85 | |
139 | |
86 | 1; |
140 | 1; |
87 | |
141 | |
… | |
… | |
105 | |
159 | |
106 | will sort according to the first element of the arrays, i.e. C<1,2,3>. |
160 | will sort according to the first element of the arrays, i.e. C<1,2,3>. |
107 | |
161 | |
108 | The custom comparison functions work similar to how C<sort> works: C<$a> |
162 | The custom comparison functions work similar to how C<sort> works: C<$a> |
109 | and C<$b> are set to the elements to be compared, and the result should be |
163 | and C<$b> are set to the elements to be compared, and the result should be |
110 | either C<-1> if C<$a> is less than C<$b>, or C<< >= 0 >> otherwise. |
164 | greater than zero then $a is greater than $b, C<0> otherwise. This means |
|
|
165 | that you can use the same function as for sorting the array, but you could |
|
|
166 | also use a simpler function that just does C<< $a > $b >>. |
111 | |
167 | |
112 | The first example above corresponds to this comparison "function": |
168 | The first example above corresponds to this comparison "function": |
113 | |
169 | |
114 | { $a <=> $b } |
170 | { $a <=> $b } |
115 | |
171 | |
… | |
… | |
118 | { $a->[0] <=> $b->[0] } |
174 | { $a->[0] <=> $b->[0] } |
119 | |
175 | |
120 | Unlike C<sort>, the default sort is numerical and it is not possible to |
176 | Unlike C<sort>, the default sort is numerical and it is not possible to |
121 | use normal subroutines. |
177 | use normal subroutines. |
122 | |
178 | |
|
|
179 | =head2 INDEXED OPERATIONS |
|
|
180 | |
|
|
181 | The functions whose names end in C<_idx> also "update the index". That |
|
|
182 | means that all elements must be array refs, with the first element being |
|
|
183 | the heap value, and the second value being the array index: |
|
|
184 | |
|
|
185 | [$value, $index, ...] |
|
|
186 | |
|
|
187 | This allows you to quickly locate an element in the array when all you |
|
|
188 | have is the array reference. |
|
|
189 | |
123 | =head1 BUGS |
190 | =head1 BUGS |
124 | |
191 | |
125 | This module works not work with tied or magical arrays or array elements. |
192 | =over 4 |
126 | |
193 | |
127 | =head1 AUTHOR |
194 | =item * Numerical comparison is always done using floatingpoint, which |
|
|
195 | usually has less precision than a 64 bit integer that perl might use |
|
|
196 | for integers internally, resulting in precision loss on the built-in |
|
|
197 | comparison. |
|
|
198 | |
|
|
199 | =item * This module does not work with tied or magical arrays or array |
|
|
200 | elements, and, in fact, will even crash when you use those. |
|
|
201 | |
|
|
202 | =item * This module can leak memory (or worse) when your comparison |
|
|
203 | function exits unexpectedly (e.g. C<last>) or throws an exception, so do |
|
|
204 | not do that. |
|
|
205 | |
|
|
206 | =back |
|
|
207 | |
|
|
208 | =head1 SEE ALSO |
|
|
209 | |
|
|
210 | This module has a rather low-level interface. If it seems daunting, you |
|
|
211 | should have a look at L<Array::Heap::ModifiablePriorityQueue>, which is |
|
|
212 | based on this module but provides more and higher-level operations with an |
|
|
213 | object-oriented API which makes it harder to make mistakes. |
|
|
214 | |
|
|
215 | A slightly less flexible (only numeric weights), but also |
|
|
216 | slightly faster variant of that module can be found as |
|
|
217 | L<Array::Heap::PriorityQueue::Numeric> on CPAN. |
|
|
218 | |
|
|
219 | =head1 AUTHOR AND CONTACT INFORMATION |
128 | |
220 | |
129 | Marc Lehmann <schmorp@schmorp.de> |
221 | Marc Lehmann <schmorp@schmorp.de> |
130 | http://home.schmorp.de/ |
222 | http://software.schmorp.de/pkg/Array-Heap |
131 | |
223 | |
132 | =cut |
224 | =cut |
133 | |
225 | |