001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.list; 018 019import java.util.AbstractList; 020import java.util.ArrayDeque; 021import java.util.Collection; 022import java.util.ConcurrentModificationException; 023import java.util.Deque; 024import java.util.Iterator; 025import java.util.ListIterator; 026import java.util.NoSuchElementException; 027 028import org.apache.commons.collections4.OrderedIterator; 029 030/** 031 * A <code>List</code> implementation that is optimised for fast insertions and 032 * removals at any index in the list. 033 * <p> 034 * This list implementation utilises a tree structure internally to ensure that 035 * all insertions and removals are O(log n). This provides much faster performance 036 * than both an <code>ArrayList</code> and a <code>LinkedList</code> where elements 037 * are inserted and removed repeatedly from anywhere in the list. 038 * <p> 039 * The following relative performance statistics are indicative of this class: 040 * <pre> 041 * get add insert iterate remove 042 * TreeList 3 5 1 2 1 043 * ArrayList 1 1 40 1 40 044 * LinkedList 5800 1 350 2 325 045 * </pre> 046 * <code>ArrayList</code> is a good general purpose list implementation. 047 * It is faster than <code>TreeList</code> for most operations except inserting 048 * and removing in the middle of the list. <code>ArrayList</code> also uses less 049 * memory as <code>TreeList</code> uses one object per entry. 050 * <p> 051 * <code>LinkedList</code> is rarely a good choice of implementation. 052 * <code>TreeList</code> is almost always a good replacement for it, although it 053 * does use slightly more memory. 054 * 055 * @since 3.1 056 */ 057public class TreeList<E> extends AbstractList<E> { 058// add; toArray; iterator; insert; get; indexOf; remove 059// TreeList = 1260;7360;3080; 160; 170;3400; 170; 060// ArrayList = 220;1480;1760; 6870; 50;1540; 7200; 061// LinkedList = 270;7360;3350;55860;290720;2910;55200; 062 063 /** The root node in the AVL tree */ 064 private AVLNode<E> root; 065 066 /** The current size of the list */ 067 private int size; 068 069 //----------------------------------------------------------------------- 070 /** 071 * Constructs a new empty list. 072 */ 073 public TreeList() { 074 super(); 075 } 076 077 /** 078 * Constructs a new empty list that copies the specified collection. 079 * 080 * @param coll the collection to copy 081 * @throws NullPointerException if the collection is null 082 */ 083 public TreeList(final Collection<? extends E> coll) { 084 super(); 085 if (!coll.isEmpty()) { 086 root = new AVLNode<>(coll); 087 size = coll.size(); 088 } 089 } 090 091 //----------------------------------------------------------------------- 092 /** 093 * Gets the element at the specified index. 094 * 095 * @param index the index to retrieve 096 * @return the element at the specified index 097 */ 098 @Override 099 public E get(final int index) { 100 checkInterval(index, 0, size() - 1); 101 return root.get(index).getValue(); 102 } 103 104 /** 105 * Gets the current size of the list. 106 * 107 * @return the current size 108 */ 109 @Override 110 public int size() { 111 return size; 112 } 113 114 /** 115 * Gets an iterator over the list. 116 * 117 * @return an iterator over the list 118 */ 119 @Override 120 public Iterator<E> iterator() { 121 // override to go 75% faster 122 return listIterator(0); 123 } 124 125 /** 126 * Gets a ListIterator over the list. 127 * 128 * @return the new iterator 129 */ 130 @Override 131 public ListIterator<E> listIterator() { 132 // override to go 75% faster 133 return listIterator(0); 134 } 135 136 /** 137 * Gets a ListIterator over the list. 138 * 139 * @param fromIndex the index to start from 140 * @return the new iterator 141 */ 142 @Override 143 public ListIterator<E> listIterator(final int fromIndex) { 144 // override to go 75% faster 145 // cannot use EmptyIterator as iterator.add() must work 146 checkInterval(fromIndex, 0, size()); 147 return new TreeListIterator<>(this, fromIndex); 148 } 149 150 /** 151 * Searches for the index of an object in the list. 152 * 153 * @param object the object to search 154 * @return the index of the object, -1 if not found 155 */ 156 @Override 157 public int indexOf(final Object object) { 158 // override to go 75% faster 159 if (root == null) { 160 return -1; 161 } 162 return root.indexOf(object, root.relativePosition); 163 } 164 165 /** 166 * Searches for the presence of an object in the list. 167 * 168 * @param object the object to check 169 * @return true if the object is found 170 */ 171 @Override 172 public boolean contains(final Object object) { 173 return indexOf(object) >= 0; 174 } 175 176 /** 177 * Converts the list into an array. 178 * 179 * @return the list as an array 180 */ 181 @Override 182 public Object[] toArray() { 183 // override to go 20% faster 184 final Object[] array = new Object[size()]; 185 if (root != null) { 186 root.toArray(array, root.relativePosition); 187 } 188 return array; 189 } 190 191 //----------------------------------------------------------------------- 192 /** 193 * Adds a new element to the list. 194 * 195 * @param index the index to add before 196 * @param obj the element to add 197 */ 198 @Override 199 public void add(final int index, final E obj) { 200 modCount++; 201 checkInterval(index, 0, size()); 202 if (root == null) { 203 root = new AVLNode<>(index, obj, null, null); 204 } else { 205 root = root.insert(index, obj); 206 } 207 size++; 208 } 209 210 /** 211 * Appends all of the elements in the specified collection to the end of this list, 212 * in the order that they are returned by the specified collection's Iterator. 213 * <p> 214 * This method runs in O(n + log m) time, where m is 215 * the size of this list and n is the size of {@code c}. 216 * 217 * @param c the collection to be added to this list 218 * @return {@code true} if this list changed as a result of the call 219 * @throws NullPointerException {@inheritDoc} 220 */ 221 @Override 222 public boolean addAll(final Collection<? extends E> c) { 223 if (c.isEmpty()) { 224 return false; 225 } 226 modCount += c.size(); 227 final AVLNode<E> cTree = new AVLNode<>(c); 228 root = root == null ? cTree : root.addAll(cTree, size); 229 size += c.size(); 230 return true; 231 } 232 233 /** 234 * Sets the element at the specified index. 235 * 236 * @param index the index to set 237 * @param obj the object to store at the specified index 238 * @return the previous object at that index 239 * @throws IndexOutOfBoundsException if the index is invalid 240 */ 241 @Override 242 public E set(final int index, final E obj) { 243 checkInterval(index, 0, size() - 1); 244 final AVLNode<E> node = root.get(index); 245 final E result = node.value; 246 node.setValue(obj); 247 return result; 248 } 249 250 /** 251 * Removes the element at the specified index. 252 * 253 * @param index the index to remove 254 * @return the previous object at that index 255 */ 256 @Override 257 public E remove(final int index) { 258 modCount++; 259 checkInterval(index, 0, size() - 1); 260 final E result = get(index); 261 root = root.remove(index); 262 size--; 263 return result; 264 } 265 266 /** 267 * Clears the list, removing all entries. 268 */ 269 @Override 270 public void clear() { 271 modCount++; 272 root = null; 273 size = 0; 274 } 275 276 //----------------------------------------------------------------------- 277 /** 278 * Checks whether the index is valid. 279 * 280 * @param index the index to check 281 * @param startIndex the first allowed index 282 * @param endIndex the last allowed index 283 * @throws IndexOutOfBoundsException if the index is invalid 284 */ 285 private void checkInterval(final int index, final int startIndex, final int endIndex) { 286 if (index < startIndex || index > endIndex) { 287 throw new IndexOutOfBoundsException("Invalid index:" + index + ", size=" + size()); 288 } 289 } 290 291 //----------------------------------------------------------------------- 292 /** 293 * Implements an AVLNode which keeps the offset updated. 294 * <p> 295 * This node contains the real work. 296 * TreeList is just there to implement {@link java.util.List}. 297 * The nodes don't know the index of the object they are holding. They 298 * do know however their position relative to their parent node. 299 * This allows to calculate the index of a node while traversing the tree. 300 * <p> 301 * The Faedelung calculation stores a flag for both the left and right child 302 * to indicate if they are a child (false) or a link as in linked list (true). 303 */ 304 static class AVLNode<E> { 305 /** The left child node or the predecessor if {@link #leftIsPrevious}.*/ 306 private AVLNode<E> left; 307 /** Flag indicating that left reference is not a subtree but the predecessor. */ 308 private boolean leftIsPrevious; 309 /** The right child node or the successor if {@link #rightIsNext}. */ 310 private AVLNode<E> right; 311 /** Flag indicating that right reference is not a subtree but the successor. */ 312 private boolean rightIsNext; 313 /** How many levels of left/right are below this one. */ 314 private int height; 315 /** The relative position, root holds absolute position. */ 316 private int relativePosition; 317 /** The stored element. */ 318 private E value; 319 320 /** 321 * Constructs a new node with a relative position. 322 * 323 * @param relativePosition the relative position of the node 324 * @param obj the value for the node 325 * @param rightFollower the node with the value following this one 326 * @param leftFollower the node with the value leading this one 327 */ 328 private AVLNode(final int relativePosition, final E obj, 329 final AVLNode<E> rightFollower, final AVLNode<E> leftFollower) { 330 this.relativePosition = relativePosition; 331 value = obj; 332 rightIsNext = true; 333 leftIsPrevious = true; 334 right = rightFollower; 335 left = leftFollower; 336 } 337 338 /** 339 * Constructs a new AVL tree from a collection. 340 * <p> 341 * The collection must be nonempty. 342 * 343 * @param coll a nonempty collection 344 */ 345 private AVLNode(final Collection<? extends E> coll) { 346 this(coll.iterator(), 0, coll.size() - 1, 0, null, null); 347 } 348 349 /** 350 * Constructs a new AVL tree from a collection. 351 * <p> 352 * This is a recursive helper for {@link #AVLNode(Collection)}. A call 353 * to this method will construct the subtree for elements {@code start} 354 * through {@code end} of the collection, assuming the iterator 355 * {@code e} already points at element {@code start}. 356 * 357 * @param iterator an iterator over the collection, which should already point 358 * to the element at index {@code start} within the collection 359 * @param start the index of the first element in the collection that 360 * should be in this subtree 361 * @param end the index of the last element in the collection that 362 * should be in this subtree 363 * @param absolutePositionOfParent absolute position of this node's 364 * parent, or 0 if this node is the root 365 * @param prev the {@code AVLNode} corresponding to element (start - 1) 366 * of the collection, or null if start is 0 367 * @param next the {@code AVLNode} corresponding to element (end + 1) 368 * of the collection, or null if end is the last element of the collection 369 */ 370 private AVLNode(final Iterator<? extends E> iterator, final int start, final int end, 371 final int absolutePositionOfParent, final AVLNode<E> prev, final AVLNode<E> next) { 372 final int mid = start + (end - start) / 2; 373 if (start < mid) { 374 left = new AVLNode<>(iterator, start, mid - 1, mid, prev, this); 375 } else { 376 leftIsPrevious = true; 377 left = prev; 378 } 379 value = iterator.next(); 380 relativePosition = mid - absolutePositionOfParent; 381 if (mid < end) { 382 right = new AVLNode<>(iterator, mid + 1, end, mid, this, next); 383 } else { 384 rightIsNext = true; 385 right = next; 386 } 387 recalcHeight(); 388 } 389 390 /** 391 * Gets the value. 392 * 393 * @return the value of this node 394 */ 395 E getValue() { 396 return value; 397 } 398 399 /** 400 * Sets the value. 401 * 402 * @param obj the value to store 403 */ 404 void setValue(final E obj) { 405 this.value = obj; 406 } 407 408 /** 409 * Locate the element with the given index relative to the 410 * offset of the parent of this node. 411 */ 412 AVLNode<E> get(final int index) { 413 final int indexRelativeToMe = index - relativePosition; 414 415 if (indexRelativeToMe == 0) { 416 return this; 417 } 418 419 final AVLNode<E> nextNode = indexRelativeToMe < 0 ? getLeftSubTree() : getRightSubTree(); 420 if (nextNode == null) { 421 return null; 422 } 423 return nextNode.get(indexRelativeToMe); 424 } 425 426 /** 427 * Locate the index that contains the specified object. 428 */ 429 int indexOf(final Object object, final int index) { 430 if (getLeftSubTree() != null) { 431 final int result = left.indexOf(object, index + left.relativePosition); 432 if (result != -1) { 433 return result; 434 } 435 } 436 if (value == null ? value == object : value.equals(object)) { 437 return index; 438 } 439 if (getRightSubTree() != null) { 440 return right.indexOf(object, index + right.relativePosition); 441 } 442 return -1; 443 } 444 445 /** 446 * Stores the node and its children into the array specified. 447 * 448 * @param array the array to be filled 449 * @param index the index of this node 450 */ 451 void toArray(final Object[] array, final int index) { 452 array[index] = value; 453 if (getLeftSubTree() != null) { 454 left.toArray(array, index + left.relativePosition); 455 } 456 if (getRightSubTree() != null) { 457 right.toArray(array, index + right.relativePosition); 458 } 459 } 460 461 /** 462 * Gets the next node in the list after this one. 463 * 464 * @return the next node 465 */ 466 AVLNode<E> next() { 467 if (rightIsNext || right == null) { 468 return right; 469 } 470 return right.min(); 471 } 472 473 /** 474 * Gets the node in the list before this one. 475 * 476 * @return the previous node 477 */ 478 AVLNode<E> previous() { 479 if (leftIsPrevious || left == null) { 480 return left; 481 } 482 return left.max(); 483 } 484 485 /** 486 * Inserts a node at the position index. 487 * 488 * @param index is the index of the position relative to the position of 489 * the parent node. 490 * @param obj is the object to be stored in the position. 491 */ 492 AVLNode<E> insert(final int index, final E obj) { 493 final int indexRelativeToMe = index - relativePosition; 494 495 if (indexRelativeToMe <= 0) { 496 return insertOnLeft(indexRelativeToMe, obj); 497 } 498 return insertOnRight(indexRelativeToMe, obj); 499 } 500 501 private AVLNode<E> insertOnLeft(final int indexRelativeToMe, final E obj) { 502 if (getLeftSubTree() == null) { 503 setLeft(new AVLNode<>(-1, obj, this, left), null); 504 } else { 505 setLeft(left.insert(indexRelativeToMe, obj), null); 506 } 507 508 if (relativePosition >= 0) { 509 relativePosition++; 510 } 511 final AVLNode<E> ret = balance(); 512 recalcHeight(); 513 return ret; 514 } 515 516 private AVLNode<E> insertOnRight(final int indexRelativeToMe, final E obj) { 517 if (getRightSubTree() == null) { 518 setRight(new AVLNode<>(+1, obj, right, this), null); 519 } else { 520 setRight(right.insert(indexRelativeToMe, obj), null); 521 } 522 if (relativePosition < 0) { 523 relativePosition--; 524 } 525 final AVLNode<E> ret = balance(); 526 recalcHeight(); 527 return ret; 528 } 529 530 //----------------------------------------------------------------------- 531 /** 532 * Gets the left node, returning null if its a faedelung. 533 */ 534 private AVLNode<E> getLeftSubTree() { 535 return leftIsPrevious ? null : left; 536 } 537 538 /** 539 * Gets the right node, returning null if its a faedelung. 540 */ 541 private AVLNode<E> getRightSubTree() { 542 return rightIsNext ? null : right; 543 } 544 545 /** 546 * Gets the rightmost child of this node. 547 * 548 * @return the rightmost child (greatest index) 549 */ 550 private AVLNode<E> max() { 551 return getRightSubTree() == null ? this : right.max(); 552 } 553 554 /** 555 * Gets the leftmost child of this node. 556 * 557 * @return the leftmost child (smallest index) 558 */ 559 private AVLNode<E> min() { 560 return getLeftSubTree() == null ? this : left.min(); 561 } 562 563 /** 564 * Removes the node at a given position. 565 * 566 * @param index is the index of the element to be removed relative to the position of 567 * the parent node of the current node. 568 */ 569 AVLNode<E> remove(final int index) { 570 final int indexRelativeToMe = index - relativePosition; 571 572 if (indexRelativeToMe == 0) { 573 return removeSelf(); 574 } 575 if (indexRelativeToMe > 0) { 576 setRight(right.remove(indexRelativeToMe), right.right); 577 if (relativePosition < 0) { 578 relativePosition++; 579 } 580 } else { 581 setLeft(left.remove(indexRelativeToMe), left.left); 582 if (relativePosition > 0) { 583 relativePosition--; 584 } 585 } 586 recalcHeight(); 587 return balance(); 588 } 589 590 private AVLNode<E> removeMax() { 591 if (getRightSubTree() == null) { 592 return removeSelf(); 593 } 594 setRight(right.removeMax(), right.right); 595 if (relativePosition < 0) { 596 relativePosition++; 597 } 598 recalcHeight(); 599 return balance(); 600 } 601 602 private AVLNode<E> removeMin() { 603 if (getLeftSubTree() == null) { 604 return removeSelf(); 605 } 606 setLeft(left.removeMin(), left.left); 607 if (relativePosition > 0) { 608 relativePosition--; 609 } 610 recalcHeight(); 611 return balance(); 612 } 613 614 /** 615 * Removes this node from the tree. 616 * 617 * @return the node that replaces this one in the parent 618 */ 619 private AVLNode<E> removeSelf() { 620 if (getRightSubTree() == null && getLeftSubTree() == null) { 621 return null; 622 } 623 if (getRightSubTree() == null) { 624 if (relativePosition > 0) { 625 left.relativePosition += relativePosition; 626 } 627 left.max().setRight(null, right); 628 return left; 629 } 630 if (getLeftSubTree() == null) { 631 right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1); 632 right.min().setLeft(null, left); 633 return right; 634 } 635 636 if (heightRightMinusLeft() > 0) { 637 // more on the right, so delete from the right 638 final AVLNode<E> rightMin = right.min(); 639 value = rightMin.value; 640 if (leftIsPrevious) { 641 left = rightMin.left; 642 } 643 right = right.removeMin(); 644 if (relativePosition < 0) { 645 relativePosition++; 646 } 647 } else { 648 // more on the left or equal, so delete from the left 649 final AVLNode<E> leftMax = left.max(); 650 value = leftMax.value; 651 if (rightIsNext) { 652 right = leftMax.right; 653 } 654 final AVLNode<E> leftPrevious = left.left; 655 left = left.removeMax(); 656 if (left == null) { 657 // special case where left that was deleted was a double link 658 // only occurs when height difference is equal 659 left = leftPrevious; 660 leftIsPrevious = true; 661 } 662 if (relativePosition > 0) { 663 relativePosition--; 664 } 665 } 666 recalcHeight(); 667 return this; 668 } 669 670 //----------------------------------------------------------------------- 671 /** 672 * Balances according to the AVL algorithm. 673 */ 674 private AVLNode<E> balance() { 675 switch (heightRightMinusLeft()) { 676 case 1 : 677 case 0 : 678 case -1 : 679 return this; 680 case -2 : 681 if (left.heightRightMinusLeft() > 0) { 682 setLeft(left.rotateLeft(), null); 683 } 684 return rotateRight(); 685 case 2 : 686 if (right.heightRightMinusLeft() < 0) { 687 setRight(right.rotateRight(), null); 688 } 689 return rotateLeft(); 690 default : 691 throw new RuntimeException("tree inconsistent!"); 692 } 693 } 694 695 /** 696 * Gets the relative position. 697 */ 698 private int getOffset(final AVLNode<E> node) { 699 if (node == null) { 700 return 0; 701 } 702 return node.relativePosition; 703 } 704 705 /** 706 * Sets the relative position. 707 */ 708 private int setOffset(final AVLNode<E> node, final int newOffest) { 709 if (node == null) { 710 return 0; 711 } 712 final int oldOffset = getOffset(node); 713 node.relativePosition = newOffest; 714 return oldOffset; 715 } 716 717 /** 718 * Sets the height by calculation. 719 */ 720 private void recalcHeight() { 721 height = Math.max( 722 getLeftSubTree() == null ? -1 : getLeftSubTree().height, 723 getRightSubTree() == null ? -1 : getRightSubTree().height) + 1; 724 } 725 726 /** 727 * Returns the height of the node or -1 if the node is null. 728 */ 729 private int getHeight(final AVLNode<E> node) { 730 return node == null ? -1 : node.height; 731 } 732 733 /** 734 * Returns the height difference right - left 735 */ 736 private int heightRightMinusLeft() { 737 return getHeight(getRightSubTree()) - getHeight(getLeftSubTree()); 738 } 739 740 private AVLNode<E> rotateLeft() { 741 final AVLNode<E> newTop = right; // can't be faedelung! 742 final AVLNode<E> movedNode = getRightSubTree().getLeftSubTree(); 743 744 final int newTopPosition = relativePosition + getOffset(newTop); 745 final int myNewPosition = -newTop.relativePosition; 746 final int movedPosition = getOffset(newTop) + getOffset(movedNode); 747 748 setRight(movedNode, newTop); 749 newTop.setLeft(this, null); 750 751 setOffset(newTop, newTopPosition); 752 setOffset(this, myNewPosition); 753 setOffset(movedNode, movedPosition); 754 return newTop; 755 } 756 757 private AVLNode<E> rotateRight() { 758 final AVLNode<E> newTop = left; // can't be faedelung 759 final AVLNode<E> movedNode = getLeftSubTree().getRightSubTree(); 760 761 final int newTopPosition = relativePosition + getOffset(newTop); 762 final int myNewPosition = -newTop.relativePosition; 763 final int movedPosition = getOffset(newTop) + getOffset(movedNode); 764 765 setLeft(movedNode, newTop); 766 newTop.setRight(this, null); 767 768 setOffset(newTop, newTopPosition); 769 setOffset(this, myNewPosition); 770 setOffset(movedNode, movedPosition); 771 return newTop; 772 } 773 774 /** 775 * Sets the left field to the node, or the previous node if that is null 776 * 777 * @param node the new left subtree node 778 * @param previous the previous node in the linked list 779 */ 780 private void setLeft(final AVLNode<E> node, final AVLNode<E> previous) { 781 leftIsPrevious = node == null; 782 left = leftIsPrevious ? previous : node; 783 recalcHeight(); 784 } 785 786 /** 787 * Sets the right field to the node, or the next node if that is null 788 * 789 * @param node the new left subtree node 790 * @param next the next node in the linked list 791 */ 792 private void setRight(final AVLNode<E> node, final AVLNode<E> next) { 793 rightIsNext = node == null; 794 right = rightIsNext ? next : node; 795 recalcHeight(); 796 } 797 798 /** 799 * Appends the elements of another tree list to this tree list by efficiently 800 * merging the two AVL trees. This operation is destructive to both trees and 801 * runs in O(log(m + n)) time. 802 * 803 * @param otherTree 804 * the root of the AVL tree to merge with this one 805 * @param currentSize 806 * the number of elements in this AVL tree 807 * @return the root of the new, merged AVL tree 808 */ 809 private AVLNode<E> addAll(AVLNode<E> otherTree, final int currentSize) { 810 final AVLNode<E> maxNode = max(); 811 final AVLNode<E> otherTreeMin = otherTree.min(); 812 813 // We need to efficiently merge the two AVL trees while keeping them 814 // balanced (or nearly balanced). To do this, we take the shorter 815 // tree and combine it with a similar-height subtree of the taller 816 // tree. There are two symmetric cases: 817 // * this tree is taller, or 818 // * otherTree is taller. 819 if (otherTree.height > height) { 820 // CASE 1: The other tree is taller than this one. We will thus 821 // merge this tree into otherTree. 822 823 // STEP 1: Remove the maximum element from this tree. 824 final AVLNode<E> leftSubTree = removeMax(); 825 826 // STEP 2: Navigate left from the root of otherTree until we 827 // find a subtree, s, that is no taller than me. (While we are 828 // navigating left, we store the nodes we encounter in a stack 829 // so that we can re-balance them in step 4.) 830 final Deque<AVLNode<E>> sAncestors = new ArrayDeque<>(); 831 AVLNode<E> s = otherTree; 832 int sAbsolutePosition = s.relativePosition + currentSize; 833 int sParentAbsolutePosition = 0; 834 while (s != null && s.height > getHeight(leftSubTree)) { 835 sParentAbsolutePosition = sAbsolutePosition; 836 sAncestors.push(s); 837 s = s.left; 838 if (s != null) { 839 sAbsolutePosition += s.relativePosition; 840 } 841 } 842 843 // STEP 3: Replace s with a newly constructed subtree whose root 844 // is maxNode, whose left subtree is leftSubTree, and whose right 845 // subtree is s. 846 maxNode.setLeft(leftSubTree, null); 847 maxNode.setRight(s, otherTreeMin); 848 if (leftSubTree != null) { 849 leftSubTree.max().setRight(null, maxNode); 850 leftSubTree.relativePosition -= currentSize - 1; 851 } 852 if (s != null) { 853 s.min().setLeft(null, maxNode); 854 s.relativePosition = sAbsolutePosition - currentSize + 1; 855 } 856 maxNode.relativePosition = currentSize - 1 - sParentAbsolutePosition; 857 otherTree.relativePosition += currentSize; 858 859 // STEP 4: Re-balance the tree and recalculate the heights of s's ancestors. 860 s = maxNode; 861 while (!sAncestors.isEmpty()) { 862 final AVLNode<E> sAncestor = sAncestors.pop(); 863 sAncestor.setLeft(s, null); 864 s = sAncestor.balance(); 865 } 866 return s; 867 } 868 otherTree = otherTree.removeMin(); 869 870 final Deque<AVLNode<E>> sAncestors = new ArrayDeque<>(); 871 AVLNode<E> s = this; 872 int sAbsolutePosition = s.relativePosition; 873 int sParentAbsolutePosition = 0; 874 while (s != null && s.height > getHeight(otherTree)) { 875 sParentAbsolutePosition = sAbsolutePosition; 876 sAncestors.push(s); 877 s = s.right; 878 if (s != null) { 879 sAbsolutePosition += s.relativePosition; 880 } 881 } 882 883 otherTreeMin.setRight(otherTree, null); 884 otherTreeMin.setLeft(s, maxNode); 885 if (otherTree != null) { 886 otherTree.min().setLeft(null, otherTreeMin); 887 otherTree.relativePosition++; 888 } 889 if (s != null) { 890 s.max().setRight(null, otherTreeMin); 891 s.relativePosition = sAbsolutePosition - currentSize; 892 } 893 otherTreeMin.relativePosition = currentSize - sParentAbsolutePosition; 894 895 s = otherTreeMin; 896 while (!sAncestors.isEmpty()) { 897 final AVLNode<E> sAncestor = sAncestors.pop(); 898 sAncestor.setRight(s, null); 899 s = sAncestor.balance(); 900 } 901 return s; 902 } 903 904// private void checkFaedelung() { 905// AVLNode maxNode = left.max(); 906// if (!maxNode.rightIsFaedelung || maxNode.right != this) { 907// throw new RuntimeException(maxNode + " should right-faedel to " + this); 908// } 909// AVLNode minNode = right.min(); 910// if (!minNode.leftIsFaedelung || minNode.left != this) { 911// throw new RuntimeException(maxNode + " should left-faedel to " + this); 912// } 913// } 914// 915// private int checkTreeDepth() { 916// int hright = (getRightSubTree() == null ? -1 : getRightSubTree().checkTreeDepth()); 917// // System.out.print("checkTreeDepth"); 918// // System.out.print(this); 919// // System.out.print(" left: "); 920// // System.out.print(_left); 921// // System.out.print(" right: "); 922// // System.out.println(_right); 923// 924// int hleft = (left == null ? -1 : left.checkTreeDepth()); 925// if (height != Math.max(hright, hleft) + 1) { 926// throw new RuntimeException( 927// "height should be max" + hleft + "," + hright + " but is " + height); 928// } 929// return height; 930// } 931// 932// private int checkLeftSubNode() { 933// if (getLeftSubTree() == null) { 934// return 0; 935// } 936// int count = 1 + left.checkRightSubNode(); 937// if (left.relativePosition != -count) { 938// throw new RuntimeException(); 939// } 940// return count + left.checkLeftSubNode(); 941// } 942// 943// private int checkRightSubNode() { 944// AVLNode right = getRightSubTree(); 945// if (right == null) { 946// return 0; 947// } 948// int count = 1; 949// count += right.checkLeftSubNode(); 950// if (right.relativePosition != count) { 951// throw new RuntimeException(); 952// } 953// return count + right.checkRightSubNode(); 954// } 955 956 /** 957 * Used for debugging. 958 */ 959 @Override 960 public String toString() { 961 return new StringBuilder() 962 .append("AVLNode(") 963 .append(relativePosition) 964 .append(',') 965 .append(left != null) 966 .append(',') 967 .append(value) 968 .append(',') 969 .append(getRightSubTree() != null) 970 .append(", faedelung ") 971 .append(rightIsNext) 972 .append(" )") 973 .toString(); 974 } 975 } 976 977 /** 978 * A list iterator over the linked list. 979 */ 980 static class TreeListIterator<E> implements ListIterator<E>, OrderedIterator<E> { 981 /** The parent list */ 982 private final TreeList<E> parent; 983 /** 984 * Cache of the next node that will be returned by {@link #next()}. 985 */ 986 private AVLNode<E> next; 987 /** 988 * The index of the next node to be returned. 989 */ 990 private int nextIndex; 991 /** 992 * Cache of the last node that was returned by {@link #next()} 993 * or {@link #previous()}. 994 */ 995 private AVLNode<E> current; 996 /** 997 * The index of the last node that was returned. 998 */ 999 private int currentIndex; 1000 /** 1001 * The modification count that the list is expected to have. If the list 1002 * doesn't have this count, then a 1003 * {@link java.util.ConcurrentModificationException} may be thrown by 1004 * the operations. 1005 */ 1006 private int expectedModCount; 1007 1008 /** 1009 * Create a ListIterator for a list. 1010 * 1011 * @param parent the parent list 1012 * @param fromIndex the index to start at 1013 */ 1014 protected TreeListIterator(final TreeList<E> parent, final int fromIndex) throws IndexOutOfBoundsException { 1015 super(); 1016 this.parent = parent; 1017 this.expectedModCount = parent.modCount; 1018 this.next = parent.root == null ? null : parent.root.get(fromIndex); 1019 this.nextIndex = fromIndex; 1020 this.currentIndex = -1; 1021 } 1022 1023 /** 1024 * Checks the modification count of the list is the value that this 1025 * object expects. 1026 * 1027 * @throws ConcurrentModificationException If the list's modification 1028 * count isn't the value that was expected. 1029 */ 1030 protected void checkModCount() { 1031 if (parent.modCount != expectedModCount) { 1032 throw new ConcurrentModificationException(); 1033 } 1034 } 1035 1036 @Override 1037 public boolean hasNext() { 1038 return nextIndex < parent.size(); 1039 } 1040 1041 @Override 1042 public E next() { 1043 checkModCount(); 1044 if (!hasNext()) { 1045 throw new NoSuchElementException("No element at index " + nextIndex + "."); 1046 } 1047 if (next == null) { 1048 next = parent.root.get(nextIndex); 1049 } 1050 final E value = next.getValue(); 1051 current = next; 1052 currentIndex = nextIndex++; 1053 next = next.next(); 1054 return value; 1055 } 1056 1057 @Override 1058 public boolean hasPrevious() { 1059 return nextIndex > 0; 1060 } 1061 1062 @Override 1063 public E previous() { 1064 checkModCount(); 1065 if (!hasPrevious()) { 1066 throw new NoSuchElementException("Already at start of list."); 1067 } 1068 if (next == null) { 1069 next = parent.root.get(nextIndex - 1); 1070 } else { 1071 next = next.previous(); 1072 } 1073 final E value = next.getValue(); 1074 current = next; 1075 currentIndex = --nextIndex; 1076 return value; 1077 } 1078 1079 @Override 1080 public int nextIndex() { 1081 return nextIndex; 1082 } 1083 1084 @Override 1085 public int previousIndex() { 1086 return nextIndex() - 1; 1087 } 1088 1089 @Override 1090 public void remove() { 1091 checkModCount(); 1092 if (currentIndex == -1) { 1093 throw new IllegalStateException(); 1094 } 1095 parent.remove(currentIndex); 1096 if (nextIndex != currentIndex) { 1097 // remove() following next() 1098 nextIndex--; 1099 } 1100 // the AVL node referenced by next may have become stale after a remove 1101 // reset it now: will be retrieved by next call to next()/previous() via nextIndex 1102 next = null; 1103 current = null; 1104 currentIndex = -1; 1105 expectedModCount++; 1106 } 1107 1108 @Override 1109 public void set(final E obj) { 1110 checkModCount(); 1111 if (current == null) { 1112 throw new IllegalStateException(); 1113 } 1114 current.setValue(obj); 1115 } 1116 1117 @Override 1118 public void add(final E obj) { 1119 checkModCount(); 1120 parent.add(nextIndex, obj); 1121 current = null; 1122 currentIndex = -1; 1123 nextIndex++; 1124 expectedModCount++; 1125 } 1126 } 1127 1128}