首页 / 软件开发 / JAVA / Commons Collections学习笔记(三)
Commons Collections学习笔记(三)2011-07-20 博客园 Phinecos这个Map类是基于红黑树构建的,每个树节点有两个域,一个存放节点的Key,一个存放节点的Value,相当于是两棵红黑树,一棵是关于key的 红黑树,一棵是关于Value的红黑树。关于红黑树的详细介绍,参考《C#与数据结构--树论--红黑树(Red Black Tree)》这篇文章。public final class DoubleOrderedMap extends AbstractMap { private Node[] rootNode = new Node[] { null, null };//根节点 public Set entrySetByValue() {//按Value获取Entry集合 if (setOfEntries[VALUE] == null) { setOfEntries[VALUE] = new AbstractSet() { public Iterator iterator() { return new DoubleOrderedMapIterator(VALUE) { protected Object doGetNext() { return lastReturnedNode; } }; } public boolean contains(Object o) { if (!(o instanceof Map.Entry)) { return false; } Map.Entry entry = (Map.Entry) o; Object key = entry.getKey(); Node node = lookup((Comparable) entry.getValue(), VALUE); return (node != null) && node.getData(KEY).equals(key); } public boolean remove(Object o) { if (!(o instanceof Map.Entry)) { return false; } Map.Entry entry = (Map.Entry) o; Object key = entry.getKey(); Node node = lookup((Comparable) entry.getValue(), VALUE); if ((node != null) && node.getData(KEY).equals(key)) { doRedBlackDelete(node); return true; } return false; } public int size() { return DoubleOrderedMap.this.size(); } public void clear() { DoubleOrderedMap.this.clear(); } }; } return setOfEntries[VALUE]; } private Object doRemove(final Comparable o, final int index) { Node node = lookup(o, index);//在红黑树中查找节点 Object rval = null; if (node != null) { rval = node.getData(oppositeIndex(index)); doRedBlackDelete(node);//在红黑树中删除指定节点 } return rval; } private Object doGet(final Comparable o, final int index) { checkNonNullComparable(o, index);//检查参数非空 Node node = lookup(o, index);//按Key或Value查找指定节点 return ((node == null)? null: node.getData(oppositeIndex(index))); } private Node lookup(final Comparable data, final int index) { Node rval = null; Node node = rootNode[index];//根节点 while (node != null) { int cmp = compare(data, node.getData(index));//与当前节点比较 if (cmp == 0) {//找到了 rval = node; break; } else {//在左子树或右子树中寻找 node = (cmp < 0) ? node.getLeft(index) : node.getRight(index); } } return rval; } private static Node leastNode(final Node node, final int index) {//返回指定节点的最右子节点 Node rval = node; if (rval != null) { while (rval.getLeft(index) != null) { rval = rval.getLeft(index); } } return rval; } private Node nextGreater(final Node node, final int index) {//返回下一个大于指定节点的节点 Node rval = null; if (node == null) { rval = null; } else if (node.getRight(index) != null) {//右子树不为空,返回右子树最左子节点 rval = leastNode(node.getRight(index), index); } else {//不断向上,只要仍然是右子节点 Node parent = node.getParent(index); Node child = node; while ((parent != null) && (child == parent.getRight(index))) { child = parent; parent = parent.getParent(index); } rval = parent; } return rval; } private void rotateLeft(final Node node, final int index) {//左旋操作 Node rightChild = node.getRight(index); node.setRight(rightChild.getLeft(index), index); if (rightChild.getLeft(index) != null) { rightChild.getLeft(index).setParent(node, index); } rightChild.setParent(node.getParent(index), index); if (node.getParent(index) == null) {//设置为根节点 rootNode[index] = rightChild; } else if (node.getParent(index).getLeft(index) == node) { node.getParent(index).setLeft(rightChild, index); } else { node.getParent(index).setRight(rightChild, index); } rightChild.setLeft(node, index); node.setParent(rightChild, index); } private void rotateRight(final Node node, final int index) {//右旋操作 Node leftChild = node.getLeft(index); node.setLeft(leftChild.getRight(index), index); if (leftChild.getRight(index) != null) { leftChild.getRight(index).setParent(node, index); } leftChild.setParent(node.getParent(index), index); if (node.getParent(index) == null) {//设置为根节点 rootNode[index] = leftChild; } else if (node.getParent(index).getRight(index) == node) { node.getParent(index).setRight(leftChild, index); } else { node.getParent(index).setLeft(leftChild, index); } leftChild.setRight(node, index); node.setParent(leftChild, index); } private void doRedBlackInsert(final Node insertedNode, final int index) {//进行红黑树节点插入后的调整 Node currentNode = insertedNode;//新插入节点置为当前节点 makeRed(currentNode, index);//标记新节点为红色 while ((currentNode != null) && (currentNode != rootNode[index])&& (isRed(currentNode.getParent (index), index))) {//确保当前节点父节点为红色才继续处理 if (isLeftChild(getParent(currentNode, index), index)) {//父节点是祖父节点的左孩子 Node y = getRightChild(getGrandParent(currentNode, index),index);//叔节点是祖父节点的右孩子 if (isRed(y, index)) {//红叔(图4) makeBlack(getParent(currentNode, index), index);//标记父节点为黑色 makeBlack(y, index);//标记叔节点为黑色 makeRed(getGrandParent(currentNode, index), index);//标记祖父节点为红色 currentNode = getGrandParent(currentNode, index);//置祖父节点为当前节点 } else {//黑叔(对应图5和图6) if (isRightChild(currentNode, index)) {//当前节点是父节点的右孩子(图6) currentNode = getParent(currentNode, index);//置父节点为当前节点 rotateLeft(currentNode, index);//左旋 } makeBlack(getParent(currentNode, index), index);//当前节点的父节点置为黑色 makeRed(getGrandParent(currentNode, index), index);//祖父节点置为红色 if (getGrandParent(currentNode, index) != null) {//对祖父节点进行右旋 rotateRight(getGrandParent(currentNode, index),index); } } } else {//父节点是祖父节点的右孩子 Node y = getLeftChild(getGrandParent(currentNode, index),index);//叔节点是祖父节点的左孩子 if (isRed(y, index)) {//红叔(图4) makeBlack(getParent(currentNode, index), index);//标记父节点为黑色 makeBlack(y, index);//标记叔节点为黑色 makeRed(getGrandParent(currentNode, index), index);//标记祖父节点为红色 currentNode = getGrandParent(currentNode, index);//置祖父节点为当前节点 } else {//黑叔(对应图7和图8) if (isLeftChild(currentNode, index)) {//当前节点是父节点的左孩子(图8) currentNode = getParent(currentNode, index);//置父节点为当前节点 rotateRight(currentNode, index);//右旋 } makeBlack(getParent(currentNode, index), index);//当前节点的父节点置为黑色 makeRed(getGrandParent(currentNode, index), index);//祖父节点置为红色 if (getGrandParent(currentNode, index) != null) {//对祖父节点进行左旋 rotateLeft(getGrandParent(currentNode, index), index); } } } } makeBlack(rootNode[index], index);//标记根节点为黑色 } private void doRedBlackDelete(final Node deletedNode) {//在红黑树中删除指定节点 for (int index = FIRST_INDEX; index < NUMBER_OF_INDICES; index++) { // if deleted node has both left and children, swap with // the next greater node if ((deletedNode.getLeft(index) != null) && (deletedNode.getRight(index) != null)) { swapPosition(nextGreater(deletedNode, index), deletedNode, index); } Node replacement = ((deletedNode.getLeft(index) != null) ? deletedNode.getLeft(index) : deletedNode.getRight(index)); if (replacement != null) { replacement.setParent(deletedNode.getParent(index), index); if (deletedNode.getParent(index) == null) { rootNode[index] = replacement; } else if (deletedNode == deletedNode.getParent(index).getLeft(index)) { deletedNode.getParent(index).setLeft(replacement, index); } else { deletedNode.getParent(index).setRight(replacement, index); } deletedNode.setLeft(null, index); deletedNode.setRight(null, index); deletedNode.setParent(null, index); if (isBlack(deletedNode, index)) { doRedBlackDeleteFixup(replacement, index); } } else { // replacement is null if (deletedNode.getParent(index) == null) { // empty tree rootNode[index] = null; } else { // deleted node had no children if (isBlack(deletedNode, index)) { doRedBlackDeleteFixup(deletedNode, index); } if (deletedNode.getParent(index) != null) { if (deletedNode == deletedNode.getParent(index) .getLeft(index)) { deletedNode.getParent(index).setLeft(null, index); } else { deletedNode.getParent(index).setRight(null, index); } deletedNode.setParent(null, index); } } } } shrink(); } private void doRedBlackDeleteFixup(final Node replacementNode, final int index){
收藏该网址