Libraryless. Click here for Pure Java version (3011L/20K).
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | * contributor license agreements. See the NOTICE file distributed with |
4 | * this work for additional information regarding copyright ownership. |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | * (the "License"); you may not use this file except in compliance with |
7 | * the License. You may obtain a copy of the License at |
8 | * |
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | * See the License for the specific language governing permissions and |
15 | * limitations under the License. |
16 | */ |
17 | |
18 | // A native long priority queue |
19 | // LongComparator support added by Stefan Reich |
20 | final sclass LongPriorityQueue implements ILongQueue { |
21 | protected int size; // number of elements currently in the queue |
22 | protected int currentCapacity; // number of elements the queue can hold w/o expanding |
23 | protected int maxSize = Int.MAX_VALUE; // max number of elements allowed in the queue |
24 | protected long[] heap; |
25 | protected final long sentinel; // represents a null return value |
26 | |
27 | LongComparator comparator; // may be null |
28 | |
29 | // too many constructors follow |
30 | |
31 | *(long sentinel) { |
32 | this(4, sentinel); |
33 | } |
34 | |
35 | *(LongComparator *comparator) { |
36 | this(-1); |
37 | } |
38 | |
39 | *(long sentinel, LongComparator *comparator) { |
40 | this(sentinel); |
41 | } |
42 | |
43 | *(int initialSize, long *sentinel) { |
44 | initialize(initialSize); |
45 | } |
46 | |
47 | *(int initialSize, int *maxSize, long *sentinel) { |
48 | initialize(initialSize); |
49 | } |
50 | |
51 | protected void initialize(int sz) { |
52 | int heapSize; |
53 | if (0 == sz) |
54 | // We allocate 1 extra to avoid if statement in top() |
55 | heapSize = 2; |
56 | else { |
57 | // NOTE: we add +1 because all access to heap is |
58 | // 1-based not 0-based. heap[0] is unused. |
59 | heapSize = Math.max(sz, sz + 1); // handle overflow |
60 | } |
61 | heap = new long[heapSize]; |
62 | currentCapacity = sz; |
63 | } |
64 | |
65 | public int getCurrentCapacity() { |
66 | return currentCapacity; |
67 | } |
68 | |
69 | public void resize(int sz) { |
70 | int heapSize; |
71 | if (sz > maxSize) { |
72 | maxSize = sz; |
73 | } |
74 | if (0 == sz) |
75 | // We allocate 1 extra to avoid if statement in top() |
76 | heapSize = 2; |
77 | else { |
78 | heapSize = Math.max(sz, sz + 1); // handle overflow |
79 | } |
80 | heap = Arrays.copyOf(heap, heapSize); |
81 | currentCapacity = sz; |
82 | } |
83 | |
84 | /** |
85 | * Adds an object to a PriorityQueue in log(size) time. If one tries to add |
86 | * more objects than maxSize from initialize an |
87 | * {@link ArrayIndexOutOfBoundsException} is thrown. |
88 | */ |
89 | public /*long*/void add(long element) { |
90 | if (size >= currentCapacity) { |
91 | int newSize = Math.min(currentCapacity <<1, maxSize); |
92 | if (newSize < currentCapacity) newSize = Integer.MAX_VALUE; // handle overflow |
93 | resize(newSize); |
94 | } |
95 | size++; |
96 | heap[size] = element; |
97 | upHeap(); |
98 | } |
99 | |
100 | /** |
101 | * Adds an object to a PriorityQueue in log(size) time. If one tries to add |
102 | * more objects than the current capacity, an |
103 | * {@link ArrayIndexOutOfBoundsException} is thrown. |
104 | */ |
105 | public void addNoCheck(long element) { |
106 | ++size; |
107 | heap[size] = element; |
108 | upHeap(); |
109 | } |
110 | |
111 | /** |
112 | * Adds an object to a PriorityQueue in log(size) time. |
113 | * It returns the smallest object (if any) that was |
114 | * dropped off the heap because it was full, or |
115 | * the sentinel value. |
116 | * |
117 | * This can be |
118 | * the given parameter (in case it is smaller than the |
119 | * full heap's minimum, and couldn't be added), or another |
120 | * object that was previously the smallest value in the |
121 | * heap and now has been replaced by a larger one, or null |
122 | * if the queue wasn't yet full with maxSize elements. |
123 | */ |
124 | public long insertWithOverflow(long element) { |
125 | if (size < maxSize) { |
126 | add(element); |
127 | return sentinel; |
128 | } else if (compare(element, heap[1]) > 0) { |
129 | long ret = heap[1]; |
130 | heap[1] = element; |
131 | updateTop(); |
132 | return ret; |
133 | } else { |
134 | return element; |
135 | } |
136 | } |
137 | |
138 | /** inserts the element and returns true if this element caused another element |
139 | * to be dropped from the queue. */ |
140 | public boolean insert(long element) { |
141 | if (size < maxSize) { |
142 | add(element); |
143 | return false; |
144 | } else if (compare(element, heap[1]) > 0) { |
145 | // long ret = heap[1]; |
146 | heap[1] = element; |
147 | updateTop(); |
148 | return true; |
149 | } else { |
150 | return false; |
151 | } |
152 | } |
153 | |
154 | /** Returns the least element of the PriorityQueue in constant time. */ |
155 | public long top() { |
156 | return heap[1]; |
157 | } |
158 | |
159 | /** Removes and returns the least element of the PriorityQueue in log(size) |
160 | time. Only valid if size() > 0. |
161 | */ |
162 | public long pop() { |
163 | long result = heap[1]; // save first value |
164 | heap[1] = heap[size]; // move last to first |
165 | size--; |
166 | downHeap(); // adjust heap |
167 | return result; |
168 | } |
169 | |
170 | // return sentinel if empty or pop() |
171 | public long poll() { |
172 | ret isEmpty() ? sentinel : pop(); |
173 | } |
174 | |
175 | /** |
176 | * Should be called when the Object at top changes values. |
177 | * @return the new 'top' element. |
178 | */ |
179 | public long updateTop() { |
180 | downHeap(); |
181 | return heap[1]; |
182 | } |
183 | |
184 | /** Returns the number of elements currently stored in the PriorityQueue. */ |
185 | public int size() { |
186 | return size; |
187 | } |
188 | |
189 | /** Returns the array used to hold the heap, with the smallest item at array[1] |
190 | * and the last (but not necessarily largest) at array[size()]. This is *not* |
191 | * fully sorted. |
192 | */ |
193 | public long[] getInternalArray() { |
194 | return heap; |
195 | } |
196 | |
197 | /** Pops the smallest n items from the heap, placing them in the internal array at |
198 | * arr[size] through arr[size-(n-1)] with the smallest (first element popped) |
199 | * being at arr[size]. The internal array is returned. |
200 | */ |
201 | public long[] sort(int n) { |
202 | while (--n >= 0) { |
203 | long result = heap[1]; // save first value |
204 | heap[1] = heap[size]; // move last to first |
205 | heap[size] = result; // place it last |
206 | size--; |
207 | downHeap(); // adjust heap |
208 | } |
209 | return heap; |
210 | } |
211 | |
212 | /** Removes all entries from the PriorityQueue. */ |
213 | public void clear() { |
214 | size = 0; |
215 | } |
216 | |
217 | private void upHeap() { |
218 | int i = size; |
219 | long node = heap[i]; // save bottom node |
220 | int j = i >>> 1; |
221 | while (j > 0 && compare(node, heap[j]) < 0) { |
222 | heap[i] = heap[j]; // shift parents down |
223 | i = j; |
224 | j = j >>> 1; |
225 | } |
226 | heap[i] = node; // install saved node |
227 | } |
228 | |
229 | private void downHeap() { |
230 | int i = 1; |
231 | long node = heap[i]; // save top node |
232 | int j = i << 1; // find smaller child |
233 | int k = j + 1; |
234 | if (k <= size && compare(heap[k], heap[j]) < 0) { |
235 | j = k; |
236 | } |
237 | while (j <= size && compare(heap[j], node) < 0) { |
238 | heap[i] = heap[j]; // shift up child |
239 | i = j; |
240 | j = i << 1; |
241 | k = j + 1; |
242 | if (k <= size && compare(heap[k], heap[j]) < 0) { |
243 | j = k; |
244 | } |
245 | } |
246 | heap[i] = node; // install saved node |
247 | } |
248 | |
249 | int compare(long a, long b) { |
250 | ret comparator == null ? cmp(a, b) : comparator.compare(a, b); |
251 | } |
252 | |
253 | public bool isEmpty() { ret size == 0; } |
254 | } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1029490 |
Snippet name: | LongPriorityQueue |
Eternal ID of this version: | #1029490/10 |
Text MD5: | ed806d38328a444a75d2382c0cf7cd5e |
Transpilation MD5: | 02827c834f895a6e70a388dbb7239c34 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-11-08 19:38:09 |
Source code size: | 7574 bytes / 254 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 223 / 517 |
Version history: | 9 change(s) |
Referenced in: | [show references] |