| ... | ... |
@@ -76,15 +76,15 @@ |
| 76 | 76 |
IN_HEAP = 0, ///< = 0. |
| 77 | 77 |
PRE_HEAP = -1, ///< = -1. |
| 78 | 78 |
POST_HEAP = -2 ///< = -2. |
| 79 | 79 |
}; |
| 80 | 80 |
|
| 81 | 81 |
private: |
| 82 |
class |
|
| 82 |
class Store; |
|
| 83 | 83 |
|
| 84 |
std::vector< |
|
| 84 |
std::vector<Store> _data; |
|
| 85 | 85 |
int _min, _head; |
| 86 | 86 |
ItemIntMap &_iim; |
| 87 | 87 |
Compare _comp; |
| 88 | 88 |
int _num_items; |
| 89 | 89 |
|
| 90 | 90 |
public: |
| ... | ... |
@@ -153,29 +153,32 @@ |
| 153 | 153 |
/// \pre \e item must not be stored in the heap. |
| 154 | 154 |
void push (const Item& item, const Prio& value) {
|
| 155 | 155 |
int i=_iim[item]; |
| 156 | 156 |
if ( i<0 ) {
|
| 157 | 157 |
int s=_data.size(); |
| 158 | 158 |
_iim.set( item,s ); |
| 159 |
|
|
| 159 |
Store st; |
|
| 160 | 160 |
st.name=item; |
| 161 |
st.prio=value; |
|
| 161 | 162 |
_data.push_back(st); |
| 162 | 163 |
i=s; |
| 163 | 164 |
} |
| 164 | 165 |
else {
|
| 165 | 166 |
_data[i].parent=_data[i].right_neighbor=_data[i].child=-1; |
| 166 | 167 |
_data[i].degree=0; |
| 167 | 168 |
_data[i].in=true; |
| 169 |
_data[i].prio=value; |
|
| 168 | 170 |
} |
| 169 |
_data[i].prio=value; |
|
| 170 | 171 |
|
| 171 |
if( 0==_num_items ) { _head=i; _min=i; }
|
|
| 172 |
else { merge(i); }
|
|
| 173 |
|
|
| 174 |
_min = findMin(); |
|
| 175 |
|
|
| 172 |
if( 0==_num_items ) {
|
|
| 173 |
_head=i; |
|
| 174 |
_min=i; |
|
| 175 |
} else {
|
|
| 176 |
merge(i); |
|
| 177 |
if( _comp(_data[i].prio, _data[_min].prio) ) _min=i; |
|
| 178 |
} |
|
| 176 | 179 |
++_num_items; |
| 177 | 180 |
} |
| 178 | 181 |
|
| 179 | 182 |
/// \brief Return the item having minimum priority. |
| 180 | 183 |
/// |
| 181 | 184 |
/// This function returns the item having minimum priority. |
| ... | ... |
@@ -205,32 +208,29 @@ |
| 205 | 208 |
_data[_min].in=false; |
| 206 | 209 |
|
| 207 | 210 |
int head_child=-1; |
| 208 | 211 |
if ( _data[_min].child!=-1 ) {
|
| 209 | 212 |
int child=_data[_min].child; |
| 210 | 213 |
int neighb; |
| 211 |
int prev=-1; |
|
| 212 | 214 |
while( child!=-1 ) {
|
| 213 | 215 |
neighb=_data[child].right_neighbor; |
| 214 | 216 |
_data[child].parent=-1; |
| 215 |
_data[child].right_neighbor= |
|
| 217 |
_data[child].right_neighbor=head_child; |
|
| 216 | 218 |
head_child=child; |
| 217 |
prev=child; |
|
| 218 | 219 |
child=neighb; |
| 219 | 220 |
} |
| 220 | 221 |
} |
| 221 | 222 |
|
| 222 |
// The first case is that there are only one root. |
|
| 223 |
if ( -1==_data[_head].right_neighbor ) {
|
|
| 223 |
if ( _data[_head].right_neighbor==-1 ) {
|
|
| 224 |
// there was only one root |
|
| 224 | 225 |
_head=head_child; |
| 225 | 226 |
} |
| 226 |
// The case where there are more roots. |
|
| 227 | 227 |
else {
|
| 228 |
// there were more roots |
|
| 228 | 229 |
if( _head!=_min ) { unlace(_min); }
|
| 229 | 230 |
else { _head=_data[_head].right_neighbor; }
|
| 230 |
|
|
| 231 | 231 |
merge(head_child); |
| 232 | 232 |
} |
| 233 | 233 |
_min=findMin(); |
| 234 | 234 |
--_num_items; |
| 235 | 235 |
} |
| 236 | 236 |
|
| ... | ... |
@@ -253,79 +253,26 @@ |
| 253 | 253 |
/// This function decreases the priority of an item to the given value. |
| 254 | 254 |
/// \param item The item. |
| 255 | 255 |
/// \param value The priority. |
| 256 | 256 |
/// \pre \e item must be stored in the heap with priority at least \e value. |
| 257 | 257 |
void decrease (Item item, const Prio& value) {
|
| 258 | 258 |
int i=_iim[item]; |
| 259 |
|
|
| 260 |
if( _comp( value,_data[i].prio ) ) {
|
|
| 261 |
_data[i].prio=value; |
|
| 262 |
|
|
| 263 |
int p_loc=_data[i].parent, loc=i; |
|
| 264 |
int parent, child, neighb; |
|
| 265 |
|
|
| 266 |
while( -1!=p_loc && _comp(_data[loc].prio,_data[p_loc].prio) ) {
|
|
| 267 |
|
|
| 268 |
// parent set for other loc_child |
|
| 269 |
child=_data[loc].child; |
|
| 270 |
while( -1!=child ) {
|
|
| 271 |
_data[child].parent=p_loc; |
|
| 272 |
child=_data[child].right_neighbor; |
|
| 273 |
} |
|
| 274 |
|
|
| 275 |
// parent set for other p_loc_child |
|
| 276 |
child=_data[p_loc].child; |
|
| 277 |
while( -1!=child ) {
|
|
| 278 |
_data[child].parent=loc; |
|
| 279 |
child=_data[child].right_neighbor; |
|
| 280 |
} |
|
| 281 |
|
|
| 282 |
child=_data[p_loc].child; |
|
| 283 |
_data[p_loc].child=_data[loc].child; |
|
| 284 |
if( child==loc ) |
|
| 285 |
child=p_loc; |
|
| 286 |
_data[loc].child=child; |
|
| 287 |
|
|
| 288 |
// left_neighb set for p_loc |
|
| 289 |
if( _data[loc].child!=p_loc ) {
|
|
| 290 |
while( _data[child].right_neighbor!=loc ) |
|
| 291 |
child=_data[child].right_neighbor; |
|
| 292 |
_data[child].right_neighbor=p_loc; |
|
| 293 |
} |
|
| 294 |
|
|
| 295 |
// left_neighb set for loc |
|
| 296 |
parent=_data[p_loc].parent; |
|
| 297 |
if( -1!=parent ) child=_data[parent].child; |
|
| 298 |
else child=_head; |
|
| 299 |
|
|
| 300 |
if( child!=p_loc ) {
|
|
| 301 |
while( _data[child].right_neighbor!=p_loc ) |
|
| 302 |
child=_data[child].right_neighbor; |
|
| 303 |
_data[child].right_neighbor=loc; |
|
| 304 |
} |
|
| 305 |
|
|
| 306 |
neighb=_data[p_loc].right_neighbor; |
|
| 307 |
_data[p_loc].right_neighbor=_data[loc].right_neighbor; |
|
| 308 |
_data[loc].right_neighbor=neighb; |
|
| 309 |
|
|
| 310 |
_data[p_loc].parent=loc; |
|
| 311 |
_data[loc].parent=parent; |
|
| 312 |
|
|
| 313 |
if( -1!=parent && _data[parent].child==p_loc ) |
|
| 314 |
_data[parent].child=loc; |
|
| 315 |
|
|
| 316 |
/*if new parent will be the first root*/ |
|
| 317 |
if( _head==p_loc ) |
|
| 318 |
_head=loc; |
|
| 319 |
|
|
| 320 |
p_loc=_data[loc].parent; |
|
| 321 |
|
|
| 259 |
int p=_data[i].parent; |
|
| 260 |
_data[i].prio=value; |
|
| 261 |
|
|
| 262 |
while( p!=-1 && _comp(value, _data[p].prio) ) {
|
|
| 263 |
_data[i].name=_data[p].name; |
|
| 264 |
_data[i].prio=_data[p].prio; |
|
| 265 |
_data[p].name=item; |
|
| 266 |
_data[p].prio=value; |
|
| 267 |
_iim[_data[i].name]=i; |
|
| 268 |
i=p; |
|
| 269 |
p=_data[p].parent; |
|
| 322 | 270 |
} |
| 323 |
if( _comp(value,_data[_min].prio) ) {
|
|
| 324 |
_min=i; |
|
| 325 |
|
|
| 271 |
_iim[item]=i; |
|
| 272 |
if ( _comp(value, _data[_min].prio) ) _min=i; |
|
| 326 | 273 |
} |
| 327 | 274 |
|
| 328 | 275 |
/// \brief Increase the priority of an item to the given value. |
| 329 | 276 |
/// |
| 330 | 277 |
/// This function increases the priority of an item to the given value. |
| 331 | 278 |
/// \param item The item. |
| ... | ... |
@@ -372,142 +319,126 @@ |
| 372 | 319 |
case IN_HEAP: |
| 373 | 320 |
break; |
| 374 | 321 |
} |
| 375 | 322 |
} |
| 376 | 323 |
|
| 377 | 324 |
private: |
| 325 |
|
|
| 326 |
// Find the minimum of the roots |
|
| 378 | 327 |
int findMin() {
|
| 379 |
int min_loc=-1, min_val; |
|
| 380 |
int x=_head; |
|
| 381 |
if( x!=-1 ) {
|
|
| 382 |
min_val=_data[x].prio; |
|
| 383 |
min_loc=x; |
|
| 384 |
x=_data[x].right_neighbor; |
|
| 385 |
|
|
| 386 |
while( x!=-1 ) {
|
|
| 328 |
if( _head!=-1 ) {
|
|
| 329 |
int min_loc=_head, min_val=_data[_head].prio; |
|
| 330 |
for( int x=_data[_head].right_neighbor; x!=-1; |
|
| 331 |
x=_data[x].right_neighbor ) {
|
|
| 387 | 332 |
if( _comp( _data[x].prio,min_val ) ) {
|
| 388 | 333 |
min_val=_data[x].prio; |
| 389 | 334 |
min_loc=x; |
| 390 | 335 |
} |
| 391 |
x=_data[x].right_neighbor; |
|
| 392 | 336 |
} |
| 337 |
return min_loc; |
|
| 393 | 338 |
} |
| 394 |
return |
|
| 339 |
else return -1; |
|
| 395 | 340 |
} |
| 396 | 341 |
|
| 342 |
// Merge the heap with another heap starting at the given position |
|
| 397 | 343 |
void merge(int a) {
|
| 398 |
interleave(a); |
|
| 399 |
|
|
| 344 |
if( _head==-1 || a==-1 ) return; |
|
| 345 |
if( _data[a].right_neighbor==-1 && |
|
| 346 |
_data[a].degree<=_data[_head].degree ) {
|
|
| 347 |
_data[a].right_neighbor=_head; |
|
| 348 |
_head=a; |
|
| 349 |
} else {
|
|
| 350 |
interleave(a); |
|
| 351 |
} |
|
| 352 |
if( _data[_head].right_neighbor==-1 ) return; |
|
| 353 |
|
|
| 400 | 354 |
int x=_head; |
| 401 |
if( -1!=x ) {
|
|
| 402 |
int x_prev=-1, x_next=_data[x].right_neighbor; |
|
| 403 |
while( -1!=x_next ) {
|
|
| 404 |
if( _data[x].degree!=_data[x_next].degree || ( -1!=_data[x_next].right_neighbor && _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
|
|
| 405 |
|
|
| 355 |
int x_prev=-1, x_next=_data[x].right_neighbor; |
|
| 356 |
while( x_next!=-1 ) {
|
|
| 357 |
if( _data[x].degree!=_data[x_next].degree || |
|
| 358 |
( _data[x_next].right_neighbor!=-1 && |
|
| 359 |
_data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
|
|
| 360 |
x_prev=x; |
|
| 361 |
x=x_next; |
|
| 362 |
} |
|
| 363 |
else {
|
|
| 364 |
if( _comp(_data[x_next].prio,_data[x].prio) ) {
|
|
| 365 |
if( x_prev==-1 ) {
|
|
| 366 |
_head=x_next; |
|
| 367 |
} else {
|
|
| 368 |
_data[x_prev].right_neighbor=x_next; |
|
| 369 |
} |
|
| 370 |
fuse(x,x_next); |
|
| 406 | 371 |
x=x_next; |
| 407 | 372 |
} |
| 408 | 373 |
else {
|
| 409 |
if( _comp(_data[x].prio,_data[x_next].prio) ) {
|
|
| 410 |
_data[x].right_neighbor=_data[x_next].right_neighbor; |
|
| 411 |
fuse(x_next,x); |
|
| 412 |
} |
|
| 413 |
else {
|
|
| 414 |
if( -1==x_prev ) { _head=x_next; }
|
|
| 415 |
else {
|
|
| 416 |
_data[x_prev].right_neighbor=x_next; |
|
| 417 |
} |
|
| 418 |
fuse(x,x_next); |
|
| 419 |
x=x_next; |
|
| 420 |
} |
|
| 374 |
_data[x].right_neighbor=_data[x_next].right_neighbor; |
|
| 375 |
fuse(x_next,x); |
|
| 421 | 376 |
} |
| 422 |
x_next=_data[x].right_neighbor; |
|
| 423 | 377 |
} |
| 378 |
x_next=_data[x].right_neighbor; |
|
| 424 | 379 |
} |
| 425 | 380 |
} |
| 426 | 381 |
|
| 382 |
// Interleave the elements of the given list into the list of the roots |
|
| 427 | 383 |
void interleave(int a) {
|
| 428 |
int other=-1, head_other=-1; |
|
| 429 |
|
|
| 430 |
while( -1!=a || -1!=_head ) {
|
|
| 431 |
if( -1==a ) {
|
|
| 432 |
if( -1==head_other ) {
|
|
| 433 |
head_other=_head; |
|
| 434 |
} |
|
| 435 |
else {
|
|
| 436 |
_data[other].right_neighbor=_head; |
|
| 437 |
} |
|
| 438 |
_head=-1; |
|
| 439 |
} |
|
| 440 |
else if( -1==_head ) {
|
|
| 441 |
if( -1==head_other ) {
|
|
| 442 |
head_other=a; |
|
| 443 |
} |
|
| 444 |
else {
|
|
| 445 |
_data[other].right_neighbor=a; |
|
| 446 |
} |
|
| 447 |
a=-1; |
|
| 384 |
int p=_head, q=a; |
|
| 385 |
int curr=_data.size(); |
|
| 386 |
_data.push_back(Store()); |
|
| 387 |
|
|
| 388 |
while( p!=-1 || q!=-1 ) {
|
|
| 389 |
if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
|
|
| 390 |
_data[curr].right_neighbor=p; |
|
| 391 |
curr=p; |
|
| 392 |
p=_data[p].right_neighbor; |
|
| 448 | 393 |
} |
| 449 | 394 |
else {
|
| 450 |
if( _data[a].degree<_data[_head].degree ) {
|
|
| 451 |
if( -1==head_other ) {
|
|
| 452 |
head_other=a; |
|
| 453 |
} |
|
| 454 |
else {
|
|
| 455 |
_data[other].right_neighbor=a; |
|
| 456 |
} |
|
| 457 |
other=a; |
|
| 458 |
a=_data[a].right_neighbor; |
|
| 459 |
} |
|
| 460 |
else {
|
|
| 461 |
if( -1==head_other ) {
|
|
| 462 |
head_other=_head; |
|
| 463 |
} |
|
| 464 |
else {
|
|
| 465 |
_data[other].right_neighbor=_head; |
|
| 466 |
} |
|
| 467 |
other=_head; |
|
| 468 |
_head=_data[_head].right_neighbor; |
|
| 469 |
} |
|
| 395 |
_data[curr].right_neighbor=q; |
|
| 396 |
curr=q; |
|
| 397 |
q=_data[q].right_neighbor; |
|
| 470 | 398 |
} |
| 471 | 399 |
} |
| 472 |
|
|
| 400 |
|
|
| 401 |
_head=_data.back().right_neighbor; |
|
| 402 |
_data.pop_back(); |
|
| 473 | 403 |
} |
| 474 | 404 |
|
| 475 |
// |
|
| 405 |
// Lace node a under node b |
|
| 476 | 406 |
void fuse(int a, int b) {
|
| 477 | 407 |
_data[a].parent=b; |
| 478 | 408 |
_data[a].right_neighbor=_data[b].child; |
| 479 | 409 |
_data[b].child=a; |
| 480 | 410 |
|
| 481 | 411 |
++_data[b].degree; |
| 482 | 412 |
} |
| 483 | 413 |
|
| 484 |
// |
|
| 414 |
// Unlace node a (if it has siblings) |
|
| 485 | 415 |
void unlace(int a) {
|
| 486 | 416 |
int neighb=_data[a].right_neighbor; |
| 487 | 417 |
int other=_head; |
| 488 | 418 |
|
| 489 | 419 |
while( _data[other].right_neighbor!=a ) |
| 490 | 420 |
other=_data[other].right_neighbor; |
| 491 | 421 |
_data[other].right_neighbor=neighb; |
| 492 | 422 |
} |
| 493 | 423 |
|
| 494 | 424 |
private: |
| 495 | 425 |
|
| 496 |
class |
|
| 426 |
class Store {
|
|
| 497 | 427 |
friend class BinomHeap; |
| 498 | 428 |
|
| 499 | 429 |
Item name; |
| 500 | 430 |
int parent; |
| 501 | 431 |
int right_neighbor; |
| 502 | 432 |
int child; |
| 503 | 433 |
int degree; |
| 504 | 434 |
bool in; |
| 505 | 435 |
Prio prio; |
| 506 | 436 |
|
| 507 |
|
|
| 437 |
Store() : parent(-1), right_neighbor(-1), child(-1), degree(0), |
|
| 438 |
in(true) {}
|
|
| 508 | 439 |
}; |
| 509 | 440 |
}; |
| 510 | 441 |
|
| 511 | 442 |
} //namespace lemon |
| 512 | 443 |
|
| 513 | 444 |
#endif //LEMON_BINOM_HEAP_H |
0 comments (0 inline)