1 25 51 package org.jgrapht.util; 52 53 import java.util.*; 54 55 56 79 public class FibonacciHeap<T> 80 { 81 82 84 87 private FibonacciHeapNode<T> minNode; 88 89 92 private int nNodes; 93 94 96 99 public FibonacciHeap() 100 { 101 } 103 105 113 public boolean isEmpty() 114 { 115 return minNode == null; 116 } 117 118 120 123 public void clear() 124 { 125 minNode = null; 126 nNodes = 0; 127 } 128 129 131 143 public void decreaseKey(FibonacciHeapNode<T> x, double k) 144 { 145 if (k > x.key) { 146 throw new IllegalArgumentException ( 147 "decreaseKey() got larger key value"); 148 } 149 150 x.key = k; 151 152 FibonacciHeapNode<T> y = x.parent; 153 154 if ((y != null) && (x.key < y.key)) { 155 cut(x, y); 156 cascadingCut(y); 157 } 158 159 if (x.key < minNode.key) { 160 minNode = x; 161 } 162 } 163 164 166 176 public void delete(FibonacciHeapNode<T> x) 177 { 178 decreaseKey(x, Double.NEGATIVE_INFINITY); 180 181 removeMin(); 183 } 184 185 187 197 public void insert(FibonacciHeapNode<T> node, double key) 198 { 199 node.key = key; 200 201 if (minNode != null) { 203 node.left = minNode; 204 node.right = minNode.right; 205 minNode.right = node; 206 node.right.left = node; 207 208 if (key < minNode.key) { 209 minNode = node; 210 } 211 } else { 212 minNode = node; 213 } 214 215 nNodes++; 216 } 217 218 220 228 public FibonacciHeapNode<T> min() 229 { 230 return minNode; 231 } 232 233 235 243 public FibonacciHeapNode<T> removeMin() 244 { 245 FibonacciHeapNode<T> z = minNode; 246 247 if (z != null) { 248 int numKids = z.degree; 249 FibonacciHeapNode<T> x = z.child; 250 FibonacciHeapNode<T> tempRight; 251 252 while (numKids > 0) { 254 tempRight = x.right; 255 256 x.left.right = x.right; 258 x.right.left = x.left; 259 260 x.left = minNode; 262 x.right = minNode.right; 263 minNode.right = x; 264 x.right.left = x; 265 266 x.parent = null; 268 x = tempRight; 269 numKids--; 270 } 271 272 z.left.right = z.right; 274 z.right.left = z.left; 275 276 if (z == z.right) { 277 minNode = null; 278 } else { 279 minNode = z.right; 280 consolidate(); 281 } 282 283 nNodes--; 285 } 286 287 return z; 288 } 289 290 292 300 public int size() 301 { 302 return nNodes; 303 } 304 305 307 318 public static <T> FibonacciHeap<T> union( 319 FibonacciHeap<T> h1, 320 FibonacciHeap<T> h2) 321 { 322 FibonacciHeap<T> h = new FibonacciHeap<T>(); 323 324 if ((h1 != null) && (h2 != null)) { 325 h.minNode = h1.minNode; 326 327 if (h.minNode != null) { 328 if (h2.minNode != null) { 329 h.minNode.right.left = h2.minNode.left; 330 h2.minNode.left.right = h.minNode.right; 331 h.minNode.right = h2.minNode; 332 h2.minNode.left = h.minNode; 333 334 if (h2.minNode.key < h1.minNode.key) { 335 h.minNode = h2.minNode; 336 } 337 } 338 } else { 339 h.minNode = h2.minNode; 340 } 341 342 h.nNodes = h1.nNodes + h2.nNodes; 343 } 344 345 return h; 346 } 347 348 350 355 public String toString() 356 { 357 if (minNode == null) { 358 return "FibonacciHeap=[]"; 359 } 360 361 Stack<FibonacciHeapNode<T>> stack = new Stack<FibonacciHeapNode<T>>(); 363 stack.push(minNode); 364 365 StringBuffer buf = new StringBuffer (512); 366 buf.append("FibonacciHeap=["); 367 368 while (!stack.empty()) { 370 FibonacciHeapNode<T> curr = stack.pop(); 371 buf.append(curr); 372 buf.append(", "); 373 374 if (curr.child != null) { 375 stack.push(curr.child); 376 } 377 378 FibonacciHeapNode<T> start = curr; 379 curr = curr.right; 380 381 while (curr != start) { 382 buf.append(curr); 383 buf.append(", "); 384 385 if (curr.child != null) { 386 stack.push(curr.child); 387 } 388 389 curr = curr.right; 390 } 391 } 392 393 buf.append(']'); 394 395 return buf.toString(); 396 } 397 398 400 408 protected void cascadingCut(FibonacciHeapNode<T> y) 409 { 410 FibonacciHeapNode<T> z = y.parent; 411 412 if (z != null) { 414 if (!y.mark) { 416 y.mark = true; 417 } else { 418 cut(y, z); 420 421 cascadingCut(z); 423 } 424 } 425 } 426 427 429 435 protected void consolidate() 436 { 437 int arraySize = nNodes + 1; 438 List<FibonacciHeapNode<T>> array = 439 new ArrayList<FibonacciHeapNode<T>>(arraySize); 440 441 for (int i = 0; i < arraySize; i++) { 443 array.add(null); 444 } 445 446 int numRoots = 0; 448 FibonacciHeapNode<T> x = minNode; 449 450 if (x != null) { 451 numRoots++; 452 x = x.right; 453 454 while (x != minNode) { 455 numRoots++; 456 x = x.right; 457 } 458 } 459 460 while (numRoots > 0) { 462 int d = x.degree; 464 FibonacciHeapNode<T> next = x.right; 465 466 while (array.get(d) != null) { 468 FibonacciHeapNode<T> y = array.get(d); 470 471 if (x.key > y.key) { 473 FibonacciHeapNode<T> temp = y; 474 y = x; 475 x = temp; 476 } 477 478 link(y, x); 480 481 array.set(d, null); 483 d++; 484 } 485 486 array.set(d, x); 489 490 x = next; 492 numRoots--; 493 } 494 495 minNode = null; 498 499 for (int i = 0; i < arraySize; i++) { 500 if (array.get(i) != null) { 501 if (minNode != null) { 503 array.get(i).left.right = array.get(i).right; 505 array.get(i).right.left = array.get(i).left; 506 507 array.get(i).left = minNode; 509 array.get(i).right = minNode.right; 510 minNode.right = array.get(i); 511 array.get(i).right.left = array.get(i); 512 513 if (array.get(i).key < minNode.key) { 515 minNode = array.get(i); 516 } 517 } else { 518 minNode = array.get(i); 519 } 520 } 521 } 522 } 523 524 526 535 protected void cut(FibonacciHeapNode<T> x, FibonacciHeapNode<T> y) 536 { 537 x.left.right = x.right; 539 x.right.left = x.left; 540 y.degree--; 541 542 if (y.child == x) { 544 y.child = x.right; 545 } 546 547 if (y.degree == 0) { 548 y.child = null; 549 } 550 551 x.left = minNode; 553 x.right = minNode.right; 554 minNode.right = x; 555 x.right.left = x; 556 557 x.parent = null; 559 560 x.mark = false; 562 } 563 564 566 574 protected void link(FibonacciHeapNode<T> y, FibonacciHeapNode<T> x) 575 { 576 y.left.right = y.right; 578 y.right.left = y.left; 579 580 y.parent = x; 582 583 if (x.child == null) { 584 x.child = y; 585 y.right = y; 586 y.left = y; 587 } else { 588 y.left = x.child; 589 y.right = x.child.right; 590 x.child.right = y; 591 y.right.left = y; 592 } 593 594 x.degree++; 596 597 y.mark = false; 599 } 600 601 } 603 604 | Popular Tags |