Node<K, V> currentNode = replacementNode; while (currentNode != rootNode[dataElement.ordinal()] && isBlack(currentNode, dataElement)) { if (currentNode.isLeftChild(dataElement)) { Node<K, V> siblingNode = getRightChild(getParent(currentNode, dataElement), dataElement); rotateLeft(getParent(currentNode, dataElement), dataElement); currentNode = rootNode[dataElement.ordinal()]; rotateRight(getParent(currentNode, dataElement), dataElement); currentNode = rootNode[dataElement.ordinal()];
for (final DataElement dataElement : DataElement.values()) { rootNode[dataElement.ordinal()] = replacement; } else if (deletedNode == deletedNode.getParent(dataElement).getLeft(dataElement)) { deletedNode.getParent(dataElement).setLeft(replacement, dataElement); rootNode[dataElement.ordinal()] = null; } else {
Node<K, V> node = rootNode[VALUE.ordinal()];
/** * do a rotate right. standard fare in the world of balanced trees * * @param node the node to be rotated * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. */ private void rotateRight(final Node<K, V> node, final DataElement dataElement) { final Node<K, V> leftChild = node.getLeft(dataElement); node.setLeft(leftChild.getRight(dataElement), dataElement); if (leftChild.getRight(dataElement) != null) { leftChild.getRight(dataElement).setParent(node, dataElement); } leftChild.setParent(node.getParent(dataElement), dataElement); if (node.getParent(dataElement) == null) { // node was the root ... now its left child is the root rootNode[dataElement.ordinal()] = leftChild; } else if (node.getParent(dataElement).getRight(dataElement) == node) { node.getParent(dataElement).setRight(leftChild, dataElement); } else { node.getParent(dataElement).setLeft(leftChild, dataElement); } leftChild.setRight(node, dataElement); node.setParent(leftChild, dataElement); }
/** * do a rotate left. standard fare in the world of balanced trees * * @param node the node to be rotated * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. */ private void rotateLeft(final Node<K, V> node, final DataElement dataElement) { final Node<K, V> rightChild = node.getRight(dataElement); node.setRight(rightChild.getLeft(dataElement), dataElement); if (rightChild.getLeft(dataElement) != null) { rightChild.getLeft(dataElement).setParent(node, dataElement); } rightChild.setParent(node.getParent(dataElement), dataElement); if (node.getParent(dataElement) == null) { // node was the root ... now its right child is the root rootNode[dataElement.ordinal()] = rightChild; } else if (node.getParent(dataElement).getLeft(dataElement) == node) { node.getParent(dataElement).setLeft(rightChild, dataElement); } else { node.getParent(dataElement).setRight(rightChild, dataElement); } rightChild.setLeft(node, dataElement); node.setParent(rightChild, dataElement); }
/** * do the actual lookup of a piece of data * * @param data the key or value to be looked up * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. * @return the desired Node, or null if there is no mapping of the * specified data */ @SuppressWarnings("unchecked") private <T extends Comparable<T>> Node<K, V> lookup(final Object data, final DataElement dataElement) { Node<K, V> rval = null; Node<K, V> node = rootNode[dataElement.ordinal()]; while (node != null) { final int cmp = compare((T) data, (T) node.getData(dataElement)); if (cmp == 0) { rval = node; break; } node = cmp < 0 ? node.getLeft(dataElement) : node.getRight(dataElement); } return rval; }
private Node<K, V> getRight(final DataElement dataElement) { return rightNode[dataElement.ordinal()]; }
private void setRight(final Node<K, V> node, final DataElement dataElement) { rightNode[dataElement.ordinal()] = node; }
private void setLeft(final Node<K, V> node, final DataElement dataElement) { leftNode[dataElement.ordinal()] = node; }
private Node<K, V> getLeft(final DataElement dataElement) { return leftNode[dataElement.ordinal()]; }
/** * Is this node black? * * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. * @return true if black (which is represented as a true boolean) */ private boolean isBlack(final DataElement dataElement) { return blackColor[dataElement.ordinal()]; }
/** * Exchange colors with another node. * * @param node the node to swap with * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. */ private void swapColors(final Node<K, V> node, final DataElement dataElement) { // Swap colors -- old hacker's trick blackColor[dataElement.ordinal()] ^= node.blackColor[dataElement.ordinal()]; node.blackColor[dataElement.ordinal()] ^= blackColor[dataElement.ordinal()]; blackColor[dataElement.ordinal()] ^= node.blackColor[dataElement.ordinal()]; }
/** * Gets the last (highest) key currently in this map. * * @return the last (highest) key currently in this sorted map * @throws NoSuchElementException if this map is empty */ @Override public K lastKey() { if (nodeCount == 0) { throw new NoSuchElementException("Map is empty"); } return greatestNode(rootNode[KEY.ordinal()], KEY).getKey(); }
/** * Gets the first (lowest) key currently in this map. * * @return the first (lowest) key currently in this sorted map * @throws NoSuchElementException if this map is empty */ @Override public K firstKey() { if (nodeCount == 0) { throw new NoSuchElementException("Map is empty"); } return leastNode(rootNode[KEY.ordinal()], KEY).getKey(); }
/** * Make this node the same color as another * * @param node the node whose color we're adopting * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. */ private void copyColor(final Node<K, V> node, final DataElement dataElement) { blackColor[dataElement.ordinal()] = node.blackColor[dataElement.ordinal()]; }
/** * Get the parent node. * * @param dataElement either {@link DataElement#KEY} key} * or the {@link DataElement#VALUE value}. * @return the parent node, may be null */ private Node<K, V> getParent(final DataElement dataElement) { return parentNode[dataElement.ordinal()]; }