diff --git a/README.md b/README.md index 4d6f181da..b0d001921 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ augmented) size. * Tested in Java 6.0 and 7.0. It might also work in Java 5.0. -# Limitations: +# Limitations * Augmentations that depend on information stored in a node's ancestors are not (easily) supported. For example, augmenting each node with the number of nodes in the left subtree is not (easily and efficiently) supported, because diff --git a/RedBlackNode.jar b/RedBlackNode.jar index 5351b7e7c..e6a079f04 100644 Binary files a/RedBlackNode.jar and b/RedBlackNode.jar differ diff --git a/src/com/github/btrekkie/red_black_node/RedBlackNode.java b/src/com/github/btrekkie/red_black_node/RedBlackNode.java index 8393fafeb..1089cf214 100644 --- a/src/com/github/btrekkie/red_black_node/RedBlackNode.java +++ b/src/com/github/btrekkie/red_black_node/RedBlackNode.java @@ -232,10 +232,11 @@ public abstract class RedBlackNode> implements Compara * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be * red. node.isRed must initially be true. The method performs any rotations by calling rotateLeft() and - * rotateRight(). + * rotateRight(). This method is more efficient than fixInsertion if "augment" is false or augment() might return + * false. * @param augment Whether to set the augmentation information for "node" and its ancestors, by calling augment(). */ - public void fixInsertion(boolean augment) { + public void fixInsertionWithoutGettingRoot(boolean augment) { if (!isRed) { throw new IllegalArgumentException("The node must be red"); } @@ -307,10 +308,35 @@ public abstract class RedBlackNode> implements Compara * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be * red. node.isRed must initially be true. The method performs any rotations by calling rotateLeft() and - * rotateRight(). + * rotateRight(). This method is more efficient than fixInsertion() if augment() might return false. */ - public void fixInsertion() { - fixInsertion(true); + public void fixInsertionWithoutGettingRoot() { + fixInsertionWithoutGettingRoot(true); + } + + /** + * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements + * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be + * red. node.isRed must initially be true. The method performs any rotations by calling rotateLeft() and + * rotateRight(). + * @param augment Whether to set the augmentation information for "node" and its ancestors, by calling augment(). + * @return The root of the resulting tree. + */ + public N fixInsertion(boolean augment) { + fixInsertionWithoutGettingRoot(augment); + return root(); + } + + /** + * Performs red-black insertion fixup. To be more precise, this fixes a tree that satisfies all of the requirements + * of red-black trees, except that this may be a red child of a red node, and if this is the root, the root may be + * red. node.isRed must initially be true. The method performs any rotations by calling rotateLeft() and + * rotateRight(). + * @return The root of the resulting tree. + */ + public N fixInsertion() { + fixInsertionWithoutGettingRoot(true); + return root(); } /** Returns a Comparator that compares instances of N using their natural order, as in N.compare. */ @@ -383,8 +409,7 @@ public abstract class RedBlackNode> implements Compara } } newNode.isRed = true; - newNode.fixInsertion(); - return root(); + return newNode.fixInsertion(); } /** @@ -757,9 +782,7 @@ public abstract class RedBlackNode> implements Compara } // Perform insertion fixup - pivot.fixInsertion(); - - return pivot.root(); + return pivot.fixInsertion(); } /** @@ -882,7 +905,7 @@ public abstract class RedBlackNode> implements Compara } last = lastPivot.left; lastParent = lastPivot; - lastPivot.fixInsertion(false); + lastPivot.fixInsertionWithoutGettingRoot(false); } lastPivot = node; node = node.left; @@ -925,7 +948,7 @@ public abstract class RedBlackNode> implements Compara } first = firstPivot.right; firstParent = firstPivot; - firstPivot.fixInsertion(false); + firstPivot.fixInsertionWithoutGettingRoot(false); } firstPivot = node; node = node.right; @@ -964,7 +987,7 @@ public abstract class RedBlackNode> implements Compara } firstPivot.left = leaf; firstPivot.right = leaf; - firstPivot.fixInsertion(false); + firstPivot.fixInsertionWithoutGettingRoot(false); for (first = firstPivot; first.parent != null; first = first.parent) { first.augment(); } @@ -982,7 +1005,7 @@ public abstract class RedBlackNode> implements Compara } lastPivot.left = leaf; lastPivot.right = leaf; - lastPivot.fixInsertion(false); + lastPivot.fixInsertionWithoutGettingRoot(false); for (last = lastPivot; last.parent != null; last = last.parent) { last.augment(); } diff --git a/src/com/github/btrekkie/tree_list/TreeList.java b/src/com/github/btrekkie/tree_list/TreeList.java index b5de0ccbc..dea9bb65c 100644 --- a/src/com/github/btrekkie/tree_list/TreeList.java +++ b/src/com/github/btrekkie/tree_list/TreeList.java @@ -133,10 +133,7 @@ public class TreeList extends AbstractList { newNode.parent = node; } - newNode.fixInsertion(); - while (root.parent != null) { - root = root.parent; - } + root = newNode.fixInsertion(); } @Override @@ -418,7 +415,7 @@ public class TreeList extends AbstractList { } prevNode = newNode; - newNode.fixInsertion(); + root = newNode.fixInsertion(); nextIndex++; haveModified = true; TreeList.this.modCount++;