@@ -13,8 +13,6 @@ See the file COPYING for details.
13
13
#include <float.h>
14
14
15
15
#define DEFAULT_CAPACITY 127
16
- #define MAX_PRIORITY DBL_MAX
17
- #define MIN_PRIORITY DBL_MIN
18
16
19
17
struct element {
20
18
void * data ;
@@ -27,8 +25,8 @@ struct priority_queue {
27
25
struct element * * elements ;
28
26
29
27
/* The following three cursors are used to iterate over the elements in the numerical order they are stored in the array, which is
30
- different from the order of priorities. Each of them has different concerns when traverse the queue Though the tipical priority-based
31
- traversal is done by the repeated invocation of priority_queue_peak_top and priority_queue_pop APIs, rather than using any cursors. */
28
+ different from the order of priorities. Each of them has different concerns when traverse the queue Though the typical priority-based
29
+ traversal is done by the repeated invocation of priority_queue_peek_top and priority_queue_pop APIs, rather than using any cursors. */
32
30
int base_cursor ; // Used in PRIORITY_QUEUE_BASE_ITERATE. It iterates from the first position and never be reset automatically.
33
31
int static_cursor ; // Used in PRIORITY_QUEUE_STATIC_ITERATE. It iterates from the last position and never be reset automatically.
34
32
int rotate_cursor ; // Used in PRIORITY_QUEUE_ROTATE_ITERATE. It iterates from the last position and can be reset when certain events happen.
@@ -101,7 +99,7 @@ static int priority_queue_double_capacity(struct priority_queue *pq)
101
99
102
100
/****** External Methods ******/
103
101
104
- struct priority_queue * priority_queue_create (double init_capacity )
102
+ struct priority_queue * priority_queue_create (int init_capacity )
105
103
{
106
104
struct priority_queue * pq = (struct priority_queue * )malloc (sizeof (struct priority_queue ));
107
105
if (!pq ) {
@@ -142,17 +140,17 @@ int priority_queue_size(struct priority_queue *pq)
142
140
int priority_queue_push (struct priority_queue * pq , void * data , double priority )
143
141
{
144
142
if (!pq ) {
145
- return 0 ;
143
+ return -1 ;
146
144
}
147
145
148
146
if (pq -> size >= pq -> capacity ) {
149
147
if (!priority_queue_double_capacity (pq )) {
150
- return 0 ;
148
+ return -1 ;
151
149
}
152
150
}
153
151
struct element * e = (struct element * )malloc (sizeof (struct element ));
154
152
if (!e ) {
155
- return 0 ;
153
+ return -1 ;
156
154
}
157
155
e -> data = data ;
158
156
e -> priority = priority ;
@@ -185,7 +183,7 @@ void *priority_queue_pop(struct priority_queue *pq)
185
183
return data ;
186
184
}
187
185
188
- void * priority_queue_peak_top (struct priority_queue * pq )
186
+ void * priority_queue_peek_top (struct priority_queue * pq )
189
187
{
190
188
if (!pq || pq -> size == 0 ) {
191
189
return NULL ;
@@ -203,7 +201,7 @@ double priority_queue_get_priority(struct priority_queue *pq, int idx)
203
201
return pq -> elements [idx ]-> priority ;
204
202
}
205
203
206
- void * priority_queue_peak_at (struct priority_queue * pq , int idx )
204
+ void * priority_queue_peek_at (struct priority_queue * pq , int idx )
207
205
{
208
206
if (!pq || pq -> size < 1 || idx < 0 || idx > pq -> size - 1 ) {
209
207
return NULL ;
@@ -215,7 +213,7 @@ void *priority_queue_peak_at(struct priority_queue *pq, int idx)
215
213
int priority_queue_update_priority (struct priority_queue * pq , void * data , double new_priority )
216
214
{
217
215
if (!pq ) {
218
- return 0 ;
216
+ return -1 ;
219
217
}
220
218
221
219
int idx = -1 ;
@@ -226,8 +224,9 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
226
224
}
227
225
}
228
226
227
+ /* If the data isn’t already in the queue, enqueue it. */
229
228
if (idx == -1 ) {
230
- return 0 ;
229
+ return priority_queue_push ( pq , data , new_priority ) ;
231
230
}
232
231
233
232
double old_priority = pq -> elements [idx ]-> priority ;
@@ -247,7 +246,7 @@ int priority_queue_update_priority(struct priority_queue *pq, void *data, double
247
246
int priority_queue_find_idx (struct priority_queue * pq , void * data )
248
247
{
249
248
if (!pq ) {
250
- return 0 ;
249
+ return -1 ;
251
250
}
252
251
253
252
for (int i = 0 ; i < pq -> size ; i ++ ) {
@@ -256,13 +255,13 @@ int priority_queue_find_idx(struct priority_queue *pq, void *data)
256
255
}
257
256
}
258
257
259
- return 0 ;
258
+ return -1 ;
260
259
}
261
260
262
261
int priority_queue_static_next (struct priority_queue * pq )
263
262
{
264
263
if (!pq || pq -> size == 0 ) {
265
- return 0 ;
264
+ return -1 ;
266
265
}
267
266
268
267
int static_idx = pq -> static_cursor ;
@@ -291,7 +290,7 @@ Advance the base cursor and return it, should be used only in PRIORITY_QUEUE_BAS
291
290
int priority_queue_base_next (struct priority_queue * pq )
292
291
{
293
292
if (!pq || pq -> size == 0 ) {
294
- return 0 ;
293
+ return -1 ;
295
294
}
296
295
297
296
int base_idx = pq -> base_cursor ;
@@ -316,7 +315,7 @@ void priority_queue_rotate_reset(struct priority_queue *pq)
316
315
int priority_queue_rotate_next (struct priority_queue * pq )
317
316
{
318
317
if (!pq || pq -> size == 0 ) {
319
- return 0 ;
318
+ return -1 ;
320
319
}
321
320
322
321
int rotate_idx = pq -> rotate_cursor ;
@@ -335,26 +334,40 @@ int priority_queue_remove(struct priority_queue *pq, int idx)
335
334
return 0 ;
336
335
}
337
336
338
- struct element * e = pq -> elements [idx ];
339
- pq -> size -- ;
340
- pq -> elements [idx ] = pq -> elements [pq -> size ];
341
- pq -> elements [pq -> size ] = NULL ;
337
+ struct element * to_delete = pq -> elements [idx ];
338
+ struct element * last_elem = pq -> elements [pq -> size - 1 ];
339
+
340
+ double old_priority = to_delete -> priority ;
341
+ double new_priority = last_elem -> priority ;
342
342
343
- sink ( pq , idx );
343
+ free ( to_delete );
344
344
345
- if (pq -> static_cursor == idx ) {
345
+ pq -> size -- ;
346
+ if (idx != pq -> size ) {
347
+ pq -> elements [idx ] = last_elem ;
348
+ pq -> elements [pq -> size ] = NULL ;
349
+
350
+ if (new_priority > old_priority ) {
351
+ swim (pq , idx );
352
+ } else if (new_priority < old_priority ) {
353
+ sink (pq , idx );
354
+ }
355
+ } else {
356
+ pq -> elements [pq -> size ] = NULL ;
357
+ }
358
+
359
+ if (pq -> static_cursor == idx && pq -> static_cursor > 0 ) {
346
360
pq -> static_cursor -- ;
347
361
}
348
- if (pq -> base_cursor == idx ) {
362
+ if (pq -> base_cursor == idx && pq -> base_cursor > 0 ) {
349
363
pq -> base_cursor -- ;
350
364
}
351
- if (pq -> rotate_cursor == idx ) {
365
+ if (pq -> rotate_cursor == idx && pq -> rotate_cursor > 0 ) {
352
366
pq -> rotate_cursor -- ;
353
367
}
354
- free (e );
355
368
369
+ // reset the rotate cursor if the removed element is before/equal to it
356
370
if (idx <= pq -> rotate_cursor ) {
357
- // reset the rotate cursor if the removed element is before/equal to it
358
371
priority_queue_rotate_reset (pq );
359
372
}
360
373
@@ -368,7 +381,9 @@ void priority_queue_delete(struct priority_queue *pq)
368
381
}
369
382
370
383
for (int i = 0 ; i < pq -> size ; i ++ ) {
371
- free (pq -> elements [i ]);
384
+ if (pq -> elements [i ]) {
385
+ free (pq -> elements [i ]);
386
+ }
372
387
}
373
388
free (pq -> elements );
374
389
free (pq );
0 commit comments