📄 treelist.java
字号:
/**
* Sets the value.
*
* @param obj the value to store
*/
void setValue(Object obj) {
this.value = obj;
}
/**
* Locate the element with the given index relative to the
* offset of the parent of this node.
*/
AVLNode get(int index) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe == 0) {
return this;
}
AVLNode nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree());
if (nextNode == null) {
return null;
}
return nextNode.get(indexRelativeToMe);
}
/**
* Locate the index that contains the specified object.
*/
int indexOf(Object object, int index) {
if (getLeftSubTree() != null) {
int result = left.indexOf(object, index + left.relativePosition);
if (result != -1) {
return result;
}
}
if (value == null ? value == object : value.equals(object)) {
return index;
}
if (getRightSubTree() != null) {
return right.indexOf(object, index + right.relativePosition);
}
return -1;
}
/**
* Stores the node and its children into the array specified.
*
* @param array the array to be filled
* @param index the index of this node
*/
void toArray(Object[] array, int index) {
array[index] = value;
if (getLeftSubTree() != null) {
left.toArray(array, index + left.relativePosition);
}
if (getRightSubTree() != null) {
right.toArray(array, index + right.relativePosition);
}
}
/**
* Gets the next node in the list after this one.
*
* @return the next node
*/
AVLNode next() {
if (rightIsNext || right == null) {
return right;
}
return right.min();
}
/**
* Gets the node in the list before this one.
*
* @return the previous node
*/
AVLNode previous() {
if (leftIsPrevious || left == null) {
return left;
}
return left.max();
}
/**
* Inserts a node at the position index.
*
* @param index is the index of the position relative to the position of
* the parent node.
* @param obj is the object to be stored in the position.
*/
AVLNode insert(int index, Object obj) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe <= 0) {
return insertOnLeft(indexRelativeToMe, obj);
} else {
return insertOnRight(indexRelativeToMe, obj);
}
}
private AVLNode insertOnLeft(int indexRelativeToMe, Object obj) {
AVLNode ret = this;
if (getLeftSubTree() == null) {
setLeft(new AVLNode(-1, obj, this, left), null);
} else {
setLeft(left.insert(indexRelativeToMe, obj), null);
}
if (relativePosition >= 0) {
relativePosition++;
}
ret = balance();
recalcHeight();
return ret;
}
private AVLNode insertOnRight(int indexRelativeToMe, Object obj) {
AVLNode ret = this;
if (getRightSubTree() == null) {
setRight(new AVLNode(+1, obj, right, this), null);
} else {
setRight(right.insert(indexRelativeToMe, obj), null);
}
if (relativePosition < 0) {
relativePosition--;
}
ret = balance();
recalcHeight();
return ret;
}
//-----------------------------------------------------------------------
/**
* Gets the left node, returning null if its a faedelung.
*/
private AVLNode getLeftSubTree() {
return (leftIsPrevious ? null : left);
}
/**
* Gets the right node, returning null if its a faedelung.
*/
private AVLNode getRightSubTree() {
return (rightIsNext ? null : right);
}
/**
* Gets the rightmost child of this node.
*
* @return the rightmost child (greatest index)
*/
private AVLNode max() {
return (getRightSubTree() == null) ? this : right.max();
}
/**
* Gets the leftmost child of this node.
*
* @return the leftmost child (smallest index)
*/
private AVLNode min() {
return (getLeftSubTree() == null) ? this : left.min();
}
/**
* Removes the node at a given position.
*
* @param index is the index of the element to be removed relative to the position of
* the parent node of the current node.
*/
AVLNode remove(int index) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe == 0) {
return removeSelf();
}
if (indexRelativeToMe > 0) {
setRight(right.remove(indexRelativeToMe), right.right);
if (relativePosition < 0) {
relativePosition++;
}
} else {
setLeft(left.remove(indexRelativeToMe), left.left);
if (relativePosition > 0) {
relativePosition--;
}
}
recalcHeight();
return balance();
}
private AVLNode removeMax() {
if (getRightSubTree() == null) {
return removeSelf();
}
setRight(right.removeMax(), right.right);
if (relativePosition < 0) {
relativePosition++;
}
recalcHeight();
return balance();
}
private AVLNode removeMin() {
if (getLeftSubTree() == null) {
return removeSelf();
}
setLeft(left.removeMin(), left.left);
if (relativePosition > 0) {
relativePosition--;
}
recalcHeight();
return balance();
}
/**
* Removes this node from the tree.
*
* @return the node that replaces this one in the parent
*/
private AVLNode removeSelf() {
if (getRightSubTree() == null && getLeftSubTree() == null) {
return null;
}
if (getRightSubTree() == null) {
if (relativePosition > 0) {
left.relativePosition += relativePosition + (relativePosition > 0 ? 0 : 1);
}
left.max().setRight(null, right);
return left;
}
if (getLeftSubTree() == null) {
right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1);
right.min().setLeft(null, left);
return right;
}
if (heightRightMinusLeft() > 0) {
// more on the right, so delete from the right
AVLNode rightMin = right.min();
value = rightMin.value;
if (leftIsPrevious) {
left = rightMin.left;
}
right = right.removeMin();
if (relativePosition < 0) {
relativePosition++;
}
} else {
// more on the left or equal, so delete from the left
AVLNode leftMax = left.max();
value = leftMax.value;
if (rightIsNext) {
right = leftMax.right;
}
AVLNode leftPrevious = left.left;
left = left.removeMax();
if (left == null) {
// special case where left that was deleted was a double link
// only occurs when height difference is equal
left = leftPrevious;
leftIsPrevious = true;
}
if (relativePosition > 0) {
relativePosition--;
}
}
recalcHeight();
return this;
}
//-----------------------------------------------------------------------
/**
* Balances according to the AVL algorithm.
*/
private AVLNode balance() {
switch (heightRightMinusLeft()) {
case 1 :
case 0 :
case -1 :
return this;
case -2 :
if (left.heightRightMinusLeft() > 0) {
setLeft(left.rotateLeft(), null);
}
return rotateRight();
case 2 :
if (right.heightRightMinusLeft() < 0) {
setRight(right.rotateRight(), null);
}
return rotateLeft();
default :
throw new RuntimeException("tree inconsistent!");
}
}
/**
* Gets the relative position.
*/
private int getOffset(AVLNode node) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -