1 |
/* pqueue.c -- Hybrid priority queue with some search functions |
/* pqueue.c -- Hybrid priority queue with some search functions |
2 |
Copyright (C) 2004 Matías Aguirre - Gonzalo Saavedra |
Copyright (C) 2004 - 2005 Matías Aguirre - Gonzalo Saavedra |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or |
This program is free software; you can redistribute it and/or |
5 |
modify it under the terms of the GNU General Public License |
modify it under the terms of the GNU General Public License |
16 |
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 |
*/ |
*/ |
18 |
|
|
19 |
|
/* |
20 |
|
* Contributions and ideas |
21 |
|
* 2005 - Maximiliano Pin |
22 |
|
*/ |
23 |
|
|
24 |
/* TODO |
/* TODO |
25 |
* 1. best return values |
* 1. best return values |
26 |
* 2. re-priority functions |
* 2. re-priority functions |
27 |
* 2. a lot of things |
* 3. a lot of things |
28 |
|
* 4. cleanups, there are so many unused static functions |
29 |
*/ |
*/ |
30 |
|
|
31 |
#include "pqueue.h" |
#include "pqueue.h" |
39 |
static pq_node ** new_heap(int); |
static pq_node ** new_heap(int); |
40 |
static void sink(int, pqueue *); |
static void sink(int, pqueue *); |
41 |
static int pos(prio_t,pqueue *); |
static int pos(prio_t,pqueue *); |
42 |
|
static int pq_requeue(pqueue *); |
43 |
|
static void float_node(int,pqueue *); |
44 |
|
static void positionate(int,pqueue *); |
45 |
|
|
46 |
|
|
47 |
/* Functions */ |
/* Functions */ |
97 |
|
|
98 |
/* returns a heap pointer with sz size */ |
/* returns a heap pointer with sz size */ |
99 |
pq_node ** new_heap(int sz){ |
pq_node ** new_heap(int sz){ |
100 |
pq_node **h=(pq_node**)calloc(sz+1,sizeof(pq_node*)); |
return (pq_node**)calloc(sz+1,sizeof(pq_node*)); |
|
int i=0; |
|
|
for(; i<sz+1; i++) |
|
|
h[i]=NULL; |
|
|
return h; |
|
101 |
} |
} |
102 |
|
|
103 |
/* |
/* |
114 |
node->pri=p; |
node->pri=p; |
115 |
node->data=d; |
node->data=d; |
116 |
|
|
117 |
q->csize++; |
int pos=++q->csize; |
|
int pos=q->csize; |
|
118 |
|
|
|
for(; pos>1 && MAX_PRI_EQ(p,q->heap[pos/2]->pri,p); pos/=2) |
|
|
q->heap[pos]=q->heap[pos/2]; |
|
119 |
q->heap[pos]=node; |
q->heap[pos]=node; |
120 |
|
positionate(pos,q); |
121 |
|
|
122 |
return p; |
return p; |
123 |
} |
} |
126 |
int pq_requeue(pqueue *q){ |
int pq_requeue(pqueue *q){ |
127 |
if(!q) |
if(!q) |
128 |
return PQERR; |
return PQERR; |
|
pq_node **old_heap=q->heap; |
|
|
q->heap=new_heap(q->size*2); |
|
|
int i=1, csize=q->csize; |
|
|
q->csize=0; |
|
129 |
|
|
130 |
for(;i<(q->size+1) && csize;i++){ |
pq_node **old_heap=q->heap; |
131 |
if(!old_heap[i]) |
if(!(q->heap=(pq_node**)realloc(q->heap,((q->size<<1)+1)*sizeof(pq_node*)))){ |
132 |
continue; |
q->heap=old_heap; |
133 |
pq_add(old_heap[i]->pri,old_heap[i]->data,q); |
return PQERR; |
|
free(old_heap[i]); |
|
|
csize--; |
|
134 |
} |
} |
135 |
|
|
136 |
free(old_heap); |
q->size<<=1; |
137 |
q->size*=2; |
int i=q->csize+1; |
138 |
|
for(;i<(q->size+1);i++) |
139 |
|
q->heap[i]=NULL; |
140 |
|
|
141 |
return POK; |
return POK; |
142 |
} |
} |
143 |
|
|
157 |
q->heap[1]=q->heap[q->csize--]; |
q->heap[1]=q->heap[q->csize--]; |
158 |
|
|
159 |
sink(1,q); |
sink(1,q); |
160 |
|
q->heap[q->csize+1]=NULL; |
161 |
|
|
162 |
void *data=pqn->data; |
void *data=pqn->data; |
163 |
pqn->data=NULL; |
pqn->data=NULL; |
171 |
return; |
return; |
172 |
int son; |
int son; |
173 |
pq_node *tmp=q->heap[pos]; |
pq_node *tmp=q->heap[pos]; |
174 |
for(; pos*2<=q->csize; pos=son){ |
for(; pos*2<(q->csize+1); pos=son){ |
175 |
son=pos*2; |
son=pos*2; |
176 |
if(son!=q->csize && MAX_PRI_EQ(q->heap[son+1]->pri,q->heap[son]->pri,q->heap[son+1]->pri)) |
if(son!=q->csize && PRI_GREATER(q->heap[son+1]->pri,q->heap[son]->pri)) |
177 |
son++; |
son++; |
178 |
if(MAX_PRI_EQ(q->heap[son]->pri,tmp->pri,q->heap[son]->pri)) |
if(PRI_GREATER(q->heap[son]->pri,tmp->pri)) |
179 |
q->heap[pos]=q->heap[son]; |
q->heap[pos]=q->heap[son]; |
180 |
else |
else |
181 |
break; |
break; |
187 |
int pq_empty(pqueue *q){ |
int pq_empty(pqueue *q){ |
188 |
if(!q) |
if(!q) |
189 |
return PQERR; |
return PQERR; |
190 |
void *d_aux; |
for(;q->csize;q->csize--) |
191 |
int i=1; |
free(q->heap[q->csize]); |
192 |
for(;i<(q->size+1);i++){ |
return POK; |
|
if(!q->heap[i]) |
|
|
continue; |
|
|
d_aux=q->heap[i]->data; |
|
|
free(q->heap[i]); |
|
|
} |
|
193 |
} |
} |
194 |
|
|
195 |
/* return the element with priority p */ |
/* return the element with priority p */ |
205 |
if(!q || !q->heap) |
if(!q || !q->heap) |
206 |
return PQERR; |
return PQERR; |
207 |
int i=1; |
int i=1; |
208 |
for(; i<(q->size+1) && (!q->heap[i] || !PRI_EQ(p,q->heap[i]->pri)) ;i++) |
for(; i<(q->csize+1) && !PRI_EQ(p,q->heap[i]->pri) ;i++) |
209 |
; |
; |
210 |
return i==q->size ? PRIERR : i; |
return i>q->csize ? PRIERR : i; |
211 |
} |
} |
212 |
|
|
213 |
/* delete the element with priority p */ |
/* delete the element with priority p */ |
218 |
pq_node *aux=q->heap[i]; |
pq_node *aux=q->heap[i]; |
219 |
q->heap[i]=q->heap[q->csize]; |
q->heap[i]=q->heap[q->csize]; |
220 |
q->csize--; |
q->csize--; |
221 |
sink(i,q); |
|
222 |
|
positionate(i,q); |
223 |
|
|
224 |
void *data=aux->data; |
void *data=aux->data; |
|
aux->data=NULL; |
|
225 |
free(aux); |
free(aux); |
226 |
return data; |
return data; |
227 |
} |
} |
238 |
|
|
239 |
int i=1; |
int i=1; |
240 |
void *data; |
void *data; |
241 |
for(;i<(pq->size+1);i++){ |
for(;i<(pq->csize+1);i++){ |
242 |
if(pq->heap[i] && pq->equals_f(pq->heap[i]->data,data2)){ |
if(pq->heap[i] && pq->equals_f(pq->heap[i]->data,data2)){ |
243 |
data=pq->heap[i]->data; |
data=pq->heap[i]->data; |
244 |
pq->heap[i]->data=NULL; |
pq->heap[i]->data=NULL; |
246 |
|
|
247 |
pq->heap[i]=pq->heap[pq->csize]; |
pq->heap[i]=pq->heap[pq->csize]; |
248 |
pq->csize--; |
pq->csize--; |
249 |
sink(i,pq); |
positionate(i,pq); |
250 |
return data; |
return data; |
251 |
} |
} |
252 |
} |
} |
263 |
return NULL; |
return NULL; |
264 |
|
|
265 |
int i=1; |
int i=1; |
266 |
for(;i<(pq->size+1);i++){ |
for(;i<(pq->csize+1);i++){ |
267 |
if(pq->heap[i] && pq->equals_f(pq->heap[i]->data,data2)) |
if(pq->heap[i] && pq->equals_f(pq->heap[i]->data,data2)) |
268 |
return pq->heap[i]->data; |
return pq->heap[i]->data; |
269 |
} |
} |
291 |
return PQERR; |
return PQERR; |
292 |
|
|
293 |
int i=1; |
int i=1; |
294 |
for(;i<(q->size+1);i++){ |
for(;i<(q->csize+1);i++){ |
295 |
if(q->heap[i] && q->equals_f(q->heap[i]->data,data)) |
if(q->heap[i] && q->equals_f(q->heap[i]->data,data)) |
296 |
break; |
break; |
297 |
} |
} |
298 |
|
|
299 |
if(i==(q->size+1)) |
if(i>q->csize) |
300 |
return NFOUNDERR; |
return NFOUNDERR; |
301 |
|
|
302 |
pq_node *node=q->heap[i]; |
q->heap[i]->pri=p; |
|
prio_t old_pri=node->pri; |
|
|
node->pri=p; |
|
303 |
|
|
304 |
if(MAX_PRI_EQ(old_pri,p,p)){ |
positionate(i,q); |
|
for(; i>1 && MAX_PRI_EQ(p,q->heap[i/2]->pri,p); i/=2) |
|
|
q->heap[i]=q->heap[i/2]; |
|
|
q->heap[i]=node; |
|
|
}else if(MAX_PRI_EQ(old_pri,p,old_pri)) |
|
|
sink(i,q); |
|
|
|
|
305 |
return p; |
return p; |
306 |
} |
} |
307 |
|
|
308 |
|
void float_node(int i,pqueue *q){ |
309 |
|
pq_node *node=q->heap[i]; |
310 |
|
prio_t p=node->pri; |
311 |
|
for(; i>1 && PRI_GREATER(p,q->heap[i/2]->pri); i/=2) |
312 |
|
q->heap[i]=q->heap[i/2]; |
313 |
|
q->heap[i]=node; |
314 |
|
} |
315 |
|
|
316 |
|
void positionate(int son_pos,pqueue *q){ |
317 |
|
if(!(son_pos/2)) |
318 |
|
return sink(son_pos,q); |
319 |
|
|
320 |
|
prio_t son_p=q->heap[son_pos]->pri, dad_p=q->heap[son_pos/2]->pri; |
321 |
|
|
322 |
|
if(PRI_GREATER(son_p,dad_p)) |
323 |
|
float_node(son_pos,q); |
324 |
|
else |
325 |
|
sink(son_pos,q); |
326 |
|
} |