1 16 package org.apache.commons.collections.list; 17 18 import java.util.AbstractList ; 19 import java.util.Collection ; 20 import java.util.ConcurrentModificationException ; 21 import java.util.Iterator ; 22 import java.util.ListIterator ; 23 import java.util.NoSuchElementException ; 24 25 import org.apache.commons.collections.OrderedIterator; 26 27 58 public class TreeList extends AbstractList { 59 64 65 private AVLNode root; 66 67 68 private int size; 69 70 74 public TreeList() { 75 super(); 76 } 77 78 84 public TreeList(Collection coll) { 85 super(); 86 addAll(coll); 87 } 88 89 96 public Object get(int index) { 97 checkInterval(index, 0, size() - 1); 98 return root.get(index).getValue(); 99 } 100 101 106 public int size() { 107 return size; 108 } 109 110 115 public Iterator iterator() { 116 return listIterator(0); 118 } 119 120 125 public ListIterator listIterator() { 126 return listIterator(0); 128 } 129 130 136 public ListIterator listIterator(int fromIndex) { 137 checkInterval(fromIndex, 0, size()); 140 return new TreeListIterator(this, fromIndex); 141 } 142 143 148 public int indexOf(Object object) { 149 if (root == null) { 151 return -1; 152 } 153 return root.indexOf(object, root.relativePosition); 154 } 155 156 161 public boolean contains(Object object) { 162 return (indexOf(object) >= 0); 163 } 164 165 170 public Object [] toArray() { 171 Object [] array = new Object [size()]; 173 if (root != null) { 174 root.toArray(array, root.relativePosition); 175 } 176 return array; 177 } 178 179 186 public void add(int index, Object obj) { 187 modCount++; 188 checkInterval(index, 0, size()); 189 if (root == null) { 190 root = new AVLNode(index, obj, null, null); 191 } else { 192 root = root.insert(index, obj); 193 } 194 size++; 195 } 196 197 205 public Object set(int index, Object obj) { 206 checkInterval(index, 0, size() - 1); 207 AVLNode node = root.get(index); 208 Object result = node.value; 209 node.setValue(obj); 210 return result; 211 } 212 213 219 public Object remove(int index) { 220 modCount++; 221 checkInterval(index, 0, size() - 1); 222 Object result = get(index); 223 root = root.remove(index); 224 size--; 225 return result; 226 } 227 228 231 public void clear() { 232 modCount++; 233 root = null; 234 size = 0; 235 } 236 237 246 private void checkInterval(int index, int startIndex, int endIndex) { 247 if (index < startIndex || index > endIndex) { 248 throw new IndexOutOfBoundsException ("Invalid index:" + index + ", size=" + size()); 249 } 250 } 251 252 265 static class AVLNode { 266 267 private AVLNode left; 268 269 private boolean leftIsPrevious; 270 271 private AVLNode right; 272 273 private boolean rightIsNext; 274 275 private int height; 276 277 private int relativePosition; 278 279 private Object value; 280 281 289 private AVLNode(int relativePosition, Object obj, AVLNode rightFollower, AVLNode leftFollower) { 290 this.relativePosition = relativePosition; 291 value = obj; 292 rightIsNext = true; 293 leftIsPrevious = true; 294 right = rightFollower; 295 left = leftFollower; 296 } 297 298 303 Object getValue() { 304 return value; 305 } 306 307 312 void setValue(Object obj) { 313 this.value = obj; 314 } 315 316 320 AVLNode get(int index) { 321 int indexRelativeToMe = index - relativePosition; 322 323 if (indexRelativeToMe == 0) { 324 return this; 325 } 326 327 AVLNode nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree()); 328 if (nextNode == null) { 329 return null; 330 } 331 return nextNode.get(indexRelativeToMe); 332 } 333 334 337 int indexOf(Object object, int index) { 338 if (getLeftSubTree() != null) { 339 int result = left.indexOf(object, index + left.relativePosition); 340 if (result != -1) { 341 return result; 342 } 343 } 344 if (value == null ? value == object : value.equals(object)) { 345 return index; 346 } 347 if (getRightSubTree() != null) { 348 return right.indexOf(object, index + right.relativePosition); 349 } 350 return -1; 351 } 352 353 359 void toArray(Object [] array, int index) { 360 array[index] = value; 361 if (getLeftSubTree() != null) { 362 left.toArray(array, index + left.relativePosition); 363 } 364 if (getRightSubTree() != null) { 365 right.toArray(array, index + right.relativePosition); 366 } 367 } 368 369 374 AVLNode next() { 375 if (rightIsNext || right == null) { 376 return right; 377 } 378 return right.min(); 379 } 380 381 386 AVLNode previous() { 387 if (leftIsPrevious || left == null) { 388 return left; 389 } 390 return left.max(); 391 } 392 393 400 AVLNode insert(int index, Object obj) { 401 int indexRelativeToMe = index - relativePosition; 402 403 if (indexRelativeToMe <= 0) { 404 return insertOnLeft(indexRelativeToMe, obj); 405 } else { 406 return insertOnRight(indexRelativeToMe, obj); 407 } 408 } 409 410 private AVLNode insertOnLeft(int indexRelativeToMe, Object obj) { 411 AVLNode ret = this; 412 413 if (getLeftSubTree() == null) { 414 setLeft(new AVLNode(-1, obj, this, left), null); 415 } else { 416 setLeft(left.insert(indexRelativeToMe, obj), null); 417 } 418 419 if (relativePosition >= 0) { 420 relativePosition++; 421 } 422 ret = balance(); 423 recalcHeight(); 424 return ret; 425 } 426 427 private AVLNode insertOnRight(int indexRelativeToMe, Object obj) { 428 AVLNode ret = this; 429 430 if (getRightSubTree() == null) { 431 setRight(new AVLNode(+1, obj, right, this), null); 432 } else { 433 setRight(right.insert(indexRelativeToMe, obj), null); 434 } 435 if (relativePosition < 0) { 436 relativePosition--; 437 } 438 ret = balance(); 439 recalcHeight(); 440 return ret; 441 } 442 443 447 private AVLNode getLeftSubTree() { 448 return (leftIsPrevious ? null : left); 449 } 450 451 454 private AVLNode getRightSubTree() { 455 return (rightIsNext ? null : right); 456 } 457 458 463 private AVLNode max() { 464 return (getRightSubTree() == null) ? this : right.max(); 465 } 466 467 472 private AVLNode min() { 473 return (getLeftSubTree() == null) ? this : left.min(); 474 } 475 476 482 AVLNode remove(int index) { 483 int indexRelativeToMe = index - relativePosition; 484 485 if (indexRelativeToMe == 0) { 486 return removeSelf(); 487 } 488 if (indexRelativeToMe > 0) { 489 setRight(right.remove(indexRelativeToMe), right.right); 490 if (relativePosition < 0) { 491 relativePosition++; 492 } 493 } else { 494 setLeft(left.remove(indexRelativeToMe), left.left); 495 if (relativePosition > 0) { 496 relativePosition--; 497 } 498 } 499 recalcHeight(); 500 return balance(); 501 } 502 503 private AVLNode removeMax() { 504 if (getRightSubTree() == null) { 505 return removeSelf(); 506 } 507 setRight(right.removeMax(), right.right); 508 if (relativePosition < 0) { 509 relativePosition++; 510 } 511 recalcHeight(); 512 return balance(); 513 } 514 515 private AVLNode removeMin() { 516 if (getLeftSubTree() == null) { 517 return removeSelf(); 518 } 519 setLeft(left.removeMin(), left.left); 520 if (relativePosition > 0) { 521 relativePosition--; 522 } 523 recalcHeight(); 524 return balance(); 525 } 526 527 private AVLNode removeSelf() { 528 if (getRightSubTree() == null && getLeftSubTree() == null) 529 return null; 530 if (getRightSubTree() == null) { 531 if (relativePosition > 0) { 532 left.relativePosition += relativePosition + (relativePosition > 0 ? 0 : 1); 533 } 534 left.max().setRight(null, right); 535 return left; 536 } 537 if (getLeftSubTree() == null) { 538 right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1); 539 right.min().setLeft(null, left); 540 return right; 541 } 542 543 if (heightRightMinusLeft() > 0) { 544 AVLNode rightMin = right.min(); 545 value = rightMin.value; 546 if (leftIsPrevious) { 547 left = rightMin.left; 548 } 549 right = right.removeMin(); 550 if (relativePosition < 0) { 551 relativePosition++; 552 } 553 } else { 554 AVLNode leftMax = left.max(); 555 value = leftMax.value; 556 if (rightIsNext) { 557 right = leftMax.right; 558 } 559 left = left.removeMax(); 560 if (relativePosition > 0) { 561 relativePosition--; 562 } 563 } 564 recalcHeight(); 565 return this; 566 } 567 568 572 private AVLNode balance() { 573 switch (heightRightMinusLeft()) { 574 case 1 : 575 case 0 : 576 case -1 : 577 return this; 578 case -2 : 579 if (left.heightRightMinusLeft() > 0) { 580 setLeft(left.rotateLeft(), null); 581 } 582 return rotateRight(); 583 case 2 : 584 if (right.heightRightMinusLeft() < 0) { 585 setRight(right.rotateRight(), null); 586 } 587 return rotateLeft(); 588 default : 589 throw new RuntimeException ("tree inconsistent!"); 590 } 591 } 592 593 596 private int getOffset(AVLNode node) { 597 if (node == null) { 598 return 0; 599 } 600 return node.relativePosition; 601 } 602 603 606 private int setOffset(AVLNode node, int newOffest) { 607 if (node == null) { 608 return 0; 609 } 610 int oldOffset = getOffset(node); 611 node.relativePosition = newOffest; 612 return oldOffset; 613 } 614 615 618 private void recalcHeight() { 619 height = Math.max( 620 getLeftSubTree() == null ? -1 : getLeftSubTree().height, 621 getRightSubTree() == null ? -1 : getRightSubTree().height) + 1; 622 } 623 624 627 private int getHeight(AVLNode node) { 628 return (node == null ? -1 : node.height); 629 } 630 631 634 private int heightRightMinusLeft() { 635 return getHeight(getRightSubTree()) - getHeight(getLeftSubTree()); 636 } 637 638 private AVLNode rotateLeft() { 639 AVLNode newTop = right; AVLNode movedNode = getRightSubTree().getLeftSubTree(); 641 642 int newTopPosition = relativePosition + getOffset(newTop); 643 int myNewPosition = -newTop.relativePosition; 644 int movedPosition = getOffset(newTop) + getOffset(movedNode); 645 646 setRight(movedNode, newTop); 647 newTop.setLeft(this, null); 648 649 setOffset(newTop, newTopPosition); 650 setOffset(this, myNewPosition); 651 setOffset(movedNode, movedPosition); 652 return newTop; 653 } 654 655 private AVLNode rotateRight() { 656 AVLNode newTop = left; AVLNode movedNode = getLeftSubTree().getRightSubTree(); 658 659 int newTopPosition = relativePosition + getOffset(newTop); 660 int myNewPosition = -newTop.relativePosition; 661 int movedPosition = getOffset(newTop) + getOffset(movedNode); 662 663 setLeft(movedNode, newTop); 664 newTop.setRight(this, null); 665 666 setOffset(newTop, newTopPosition); 667 setOffset(this, myNewPosition); 668 setOffset(movedNode, movedPosition); 669 return newTop; 670 } 671 672 private void setLeft(AVLNode node, AVLNode previous) { 673 leftIsPrevious = (node == null); 674 left = (leftIsPrevious ? previous : node); 675 recalcHeight(); 676 } 677 678 private void setRight(AVLNode node, AVLNode next) { 679 rightIsNext = (node == null); 680 right = (rightIsNext ? next : node); 681 recalcHeight(); 682 } 683 684 736 739 public String toString() { 740 return "AVLNode(" + relativePosition + "," + (left != null) + "," + value + 741 "," + (getRightSubTree() != null) + ", faedelung " + rightIsNext + " )"; 742 } 743 } 744 745 748 static class TreeListIterator implements ListIterator , OrderedIterator { 749 750 protected final TreeList parent; 751 755 protected AVLNode next; 756 759 protected int nextIndex; 760 768 protected AVLNode current; 769 772 protected int currentIndex; 773 779 protected int expectedModCount; 780 781 787 protected TreeListIterator(TreeList parent, int fromIndex) throws IndexOutOfBoundsException { 788 super(); 789 this.parent = parent; 790 this.expectedModCount = parent.modCount; 791 this.next = (parent.root == null ? null : parent.root.get(fromIndex)); 792 this.nextIndex = fromIndex; 793 } 794 795 802 protected void checkModCount() { 803 if (parent.modCount != expectedModCount) { 804 throw new ConcurrentModificationException (); 805 } 806 } 807 808 public boolean hasNext() { 809 return (nextIndex < parent.size()); 810 } 811 812 public Object next() { 813 checkModCount(); 814 if (!hasNext()) { 815 throw new NoSuchElementException ("No element at index " + nextIndex + "."); 816 } 817 if (next == null) { 818 next = parent.root.get(nextIndex); 819 } 820 Object value = next.getValue(); 821 current = next; 822 currentIndex = nextIndex++; 823 next = next.next(); 824 return value; 825 } 826 827 public boolean hasPrevious() { 828 return (nextIndex > 0); 829 } 830 831 public Object previous() { 832 checkModCount(); 833 if (!hasPrevious()) { 834 throw new NoSuchElementException ("Already at start of list."); 835 } 836 if (next == null) { 837 next = parent.root.get(nextIndex - 1); 838 } else { 839 next = next.previous(); 840 } 841 Object value = next.getValue(); 842 current = next; 843 currentIndex = --nextIndex; 844 return value; 845 } 846 847 public int nextIndex() { 848 return nextIndex; 849 } 850 851 public int previousIndex() { 852 return nextIndex() - 1; 853 } 854 855 public void remove() { 856 checkModCount(); 857 if (current == null) { 858 throw new IllegalStateException (); 859 } 860 parent.remove(currentIndex); 861 current = null; 862 currentIndex = -1; 863 nextIndex--; 864 expectedModCount++; 865 } 866 867 public void set(Object obj) { 868 checkModCount(); 869 if (current == null) { 870 throw new IllegalStateException (); 871 } 872 current.setValue(obj); 873 } 874 875 public void add(Object obj) { 876 checkModCount(); 877 parent.add(nextIndex, obj); 878 current = null; 879 currentIndex = -1; 880 nextIndex++; 881 expectedModCount++; 882 } 883 } 884 885 } 886 | Popular Tags |