红黑树的Java实现
来源:互联网 发布:淘宝可以修改用户名吗 编辑:程序博客网 时间:2024/05/22 08:17
概念
红黑树是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。它是在1972年由Rudolf Bayer发明的,他称之为”对称二叉B树”,它现代的名字是在 Leo J. Guibas 和 Robert Sedgewick 于1978年写的一篇论文中获得的。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
红黑树是一种很有意思的平衡检索树。它的统计性能要好于平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。
背景和术语
红黑树是一种特定类型的二叉树,它是在计算机科学中用来组织数据比如数字的块的一种结构。所有数据块都存储在节点中。这些节点中的某一个节点总是担当启始位置的功能,它不是任何节点的儿子;我们称之为根节点或根。它有最多两个”儿子”,都是它连接到的其他节点。所有这些儿子都可以有自己的儿子,以此类推。这样根节点就有了把它连接到在树中任何其他节点的路径。
如果一个节点没有儿子,我们称之为叶子节点,因为在直觉上它是在树的边缘上。子树是从特定节点可以延伸到的树的某一部分,其自身被当作一个树。在红黑树中,叶子被假定为 null 或空。
由于红黑树也是二叉查找树,它们当中每一个节点的比较值都必须大于或等于在它的左子树中的所有节点,并且小于或等于在它的右子树中的所有节点。这确保红黑树运作时能够快速地在树中查找给定的值。
用途和好处
红黑树和AVL树一样都对插入时间、删除时间和查找时间提供了最好可能的最坏情况担保。这不只是使它们在时间敏感的应用如即时应用(real time application)中有价值,而且使它们有在提供最坏情况担保的其他数据结构中作为建造板块的价值。例如,在计算几何中使用的很多数据结构都可以基于红黑树。
红黑树在函数式编程中也特别有用,在这里它们是最常用的持久数据结构之一,它们用来构造关联数组和集合,在突变之后它们能保持为以前的版本。除了O(log n)的时间之外,红黑树的持久版本对每次插入或删除需要O(log n)的空间。
红黑树是 2-3-4树的一种等同。换句话说,对于每个 2-3-4 树,都存在至少一个数据元素是同样次序的红黑树。在 2-3-4 树上的插入和删除操作也等同于在红黑树中颜色翻转和旋转。这使得 2-3-4 树成为理解红黑树背后的逻辑的重要工具,这也是很多介绍算法的教科书在红黑树之前介绍 2-3-4 树的原因,尽管 2-3-4 树在实践中不经常使用。
属性
红黑树是每个节点都有颜色特性的二叉查找树,颜色的值是红色或黑色之一。除了二叉查找树带有的一般要求,我们对任何有效的红黑树加以如下增补要求:
1.节点是红色或黑色。
2.根是黑色。
3.所有叶子(外部节点)都是黑色。
4.每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
5.从每个叶子到根的所有路径都包含相同数目的黑色节点。
这些约束强制了红黑树的关键属性: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值都要求与树的高度成比例的最坏情况时间,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。
要知道为什么这些特性确保了这个结果,注意到属性4导致了路径不能有两个毗连的红色节点就足够了。最短的可能路径都是黑色节点,最长的可能路径有交替的红色和黑色节点。因为根据属性5所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。
在很多树数据结构的表示中,一个节点有可能只有一个儿子,而叶子节点包含数据。用这种范例表示红黑树是可能的,但是这会改变一些属性并使算法复杂。为此,本文中我们使用 “nil 叶子” 或”空(null)叶子”,如下图所示,它不包含数据而只充当树在此结束的指示。这些节点在绘图中经常被省略,导致了这些树好像同上述原则相矛盾,而实际上不是这样。与此有关的结论是所有节点都有两个儿子,尽管其中的一个或两个可能是空叶子。
操作
在红黑树上只读操作不需要对用于二叉查找树的操作做出修改,因为它也二叉查找树。但是,在插入和删除之后,红黑属性可能变得违规。恢复红黑属性需要少量(O(log n))的颜色变更(这在实践中是非常快速的)并且不超过三次树旋转(对于插入是两次)。这允许插入和删除保持为 O(log n) 次,但是它导致了非常复杂的操作。
实现
红黑树可能是要考虑情况最多的BST树了,它有自己的规则(见代码的注释),通过这些规则可以保证花费较小的代价来达到相对平衡。
注意,红黑树仍然不是平衡树,但是统计性能要好于AVL树。
要保持红黑树的规则,主要通过两类操作,一类是换色,一类还是旋转。
红黑树插入主要要解决红-红冲突,而删除主要则解决“双黑”
同样,红黑树的删除节点实现是最复杂的,不过,复杂也就在于考虑的情况多,掌握了这几种情况实现还是不困难。
其实,红黑树其实是一颗扩充的二叉树,所以也是满二叉树,其空节点可以看做是扩充的叶节点。但是红黑树的扩充叶节点是有特殊意义的。
下面是代码:
(取自:http://blog.csdn.net/yaoweijq/article/details/5833770)
package com.yaowei.datastructure; public class RBTreeNode<E> implements Comparable<RBTreeNode<E>>{ static boolean RED = true; static boolean BLACK = false; private E value; //父结点 private RBTreeNode<E> parentNode; //左子结点 private RBTreeNode<E> leftNode; //右子结点 private RBTreeNode<E> rightNode; //结点的颜色,默认颜色为黑色 private boolean color; //构造方法 public RBTreeNode(){ this.value = null; this.parentNode = null; this.leftNode = null; this.rightNode = null; this.color = RBTreeNode.BLACK; } public RBTreeNode(E value){ this.value = value; this.parentNode = null; this.leftNode = null; this.rightNode = null; this.color = RBTreeNode.BLACK; } public RBTreeNode(E value,boolean color){ this.value = value; this.parentNode = null; this.leftNode = null; this.rightNode = null; this.color = color; } public RBTreeNode(E value,RBTreeNode<E>parentNode){ this.value = value; this.parentNode = parentNode; this.leftNode = null; this.rightNode = null; this.color = RBTreeNode.BLACK; } public RBTreeNode(E value,RBTreeNode<E>parentNode,boolean color){ this.value = value; this.parentNode = parentNode; this.leftNode = null; this.rightNode = null; this.color = color; } //构造方法结束 //get set方法 public E getValue(){ return this.value; } public void setValue(E value){ this.value = value; } public RBTreeNode<E> getParentNode(){ return this.parentNode; } public void setParentNode(RBTreeNode<E>parentNode){ this.parentNode = parentNode; } public RBTreeNode<E> getLeftNode(){ return this.leftNode; } public void setLeftNode(RBTreeNode<E>leftNode){ this.leftNode = leftNode; } public RBTreeNode<E> getRightNode(){ return this.rightNode; } public void setRightNode(RBTreeNode<E>rightNode){ this.rightNode = rightNode; } public boolean getColor(){ return this.color; } public void setColor(boolean color){ this.color = color; } //get set方法结束 public boolean equals(Object o){ if(o instanceof RBTreeNode){ RBTreeNode<E> node = (RBTreeNode<E>)o; if(this.compareTo(node) == 0) return true; return false; }else{ return false; } } public int hashCode(){ if(this.value == null) return 0; return String.valueOf(value).hashCode(); } public int compareTo(RBTreeNode<E>node){ E obj = node.getValue(); if(value instanceof String){ return ((String)value).compareTo((String)obj); }else if(value instanceof Character){ return (String.valueOf(value)).compareTo(String.valueOf(obj)); }else if((value instanceof Byte)){ if(((Byte)value)>((Byte)obj)){ return 1; }else if(((Byte)value) == ((Byte)obj)){ return 0; }else{ return -1; } }else if(value instanceof Short){ if(((Short)value)>((Short)obj)){ return 1; }else if(((Short)value) == ((Short)obj)){ return 0; }else{ return -1; } }else if(value instanceof Integer){ if(((Integer)value)>((Integer)obj)){ return 1; }else if(((Integer)value) == ((Integer)obj)){ return 0; }else{ return -1; } }else if(value instanceof Float){ if(((Float)value)>((Float)obj)){ return 1; }else if(((Float)value) == ((Float)obj)){ return 0; }else{ return -1; } }else if(value instanceof Long){ if(((Long)value)>((Long)obj)){ return 1; }else if(((Long)value) == ((Long)obj)){ return 0; }else{ return -1; } }else if(value instanceof Double){ if(((Double)value)>((Double)obj)){ return 1; }else if(((Double)value) == ((Double)obj)){ return 0; }else{ return -1; } } return 0; } }
package com.yaowei.datastructure; /** * 红黑树 * 首先是一个二叉搜索树 * 然后具有四个性质 * 性质1. 结点是红色或黑色 * 性质2. 根是黑色 * 性质3. 每个红色结点的两个子结点都是黑色 * (从每个叶子到根的所有路径上不能有两个连续的红色结点) * 性质4. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点 * @author Administrator * * @param <E> */ public class RBTree<E> { //红黑树的根结点 private RBTreeNode<E> rootNode; //构造方法 public RBTree(){ this.rootNode = null; } //构造方法结束 //get set方法 public RBTreeNode<E> getRootNode(){ return this.rootNode; } public void setRootNode(RBTreeNode<E>rootNode){ this.rootNode = rootNode; } //get set方法结束 public RBTreeNode<E> parentOf(RBTreeNode<E>node){ return node == null?null:node.getParentNode(); } public RBTreeNode<E> leftOf(RBTreeNode<E>node){ return node == null?null:node.getLeftNode(); } public RBTreeNode<E> rightOf(RBTreeNode<E>node){ return node == null?null:node.getRightNode(); } public boolean colorOf(RBTreeNode<E>node){ return node == null?RBTreeNode.BLACK:node.getColor(); } public void setColor(RBTreeNode<E>node,boolean color){ if(node == null) return; node.setColor(color); } /** * 这个方法的作用是啥?<br/> * 三种情况:<br/> * 1.t为空,返回空<br/> * * 2.t的右子结点不为空<br/> * * 返回t的右子树的最小结点(左下方的结点)<br/> * * 3.t的右子结点为空<br/> * * p指向t的父结点 * ch指向t * 然后跑个while循环 * 当p不为空并且ch是p的右子结点时<br/> * * ch指向p * p指向p的父结点 * while循环结束 * 最后return p * @param t * @return */ //static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) { private RBTreeNode<E> successor(RBTreeNode<E> t) { if (t == null) return null; /** * t的右子结点不为空 */ //else if (t.right != null) { else if (t.getRightNode() != null) { /** * p指向t的右子结点 */ //Entry<K,V> p = t.right; RBTreeNode<E> p = t.getRightNode(); /** * 一直到p的子树的最左下结点 * 然后将此结点返回 */ //while (p.left != null) while (p.getLeftNode() != null) //p = p.left; p = p.getLeftNode(); return p; } else {//t的右子结点为空 /** * p指向t的父结点 */ //Entry<K,V> p = t.parent; RBTreeNode<E> p = t.getParentNode(); /** * ch指向t */ //Entry<K,V> ch = t; RBTreeNode<E> ch = t; /** * 循环条件: * p非空 * ch是p的右子结点 */ //while (p != null && ch == p.right) { while (p != null && ch == p.getRightNode()) { ch = p; //p = p.parent; p = p.getParentNode(); } return p; } } //static <K,V> Entry<K,V> predecessor(Entry<K,V> t) { private RBTreeNode<E> predecessor(RBTreeNode<E> t) { if (t == null) return null; //else if (t.left != null) { else if (t.getLeftNode() != null) { //Entry<K,V> p = t.left; RBTreeNode<E> p = t.getLeftNode(); //while (p.right != null) while (p.getRightNode() != null) //p = p.right; p = p.getRightNode(); return p; } else { //Entry<K,V> p = t.parent; RBTreeNode<E> p = t.getParentNode(); //Entry<K,V> ch = t; RBTreeNode<E> ch = t; //while (p != null && ch == p.left) { while (p != null && ch == p.getLeftNode()) { ch = p; //p = p.parent; p = p.getParentNode(); } return p; } } /** * 围绕某个结点左旋转 * @param node */ private void rotateLeft(RBTreeNode<E>node){ if (node != null) { /** * 得到node的右子结点 */ //Entry<K,V> r = p.right; RBTreeNode<E> rightNode = node.getRightNode(); /** * 把node的右子结点设为rightNode的左子结点 */ //p.right = r.left; node.setRightNode(rightNode.getLeftNode()); /** * 如果rightNode的左子结点非空 * 就把rightNode的左子结点的父结点设为node */ //if (r.left != null) if(rightNode.getLeftNode()!=null) //r.left.parent = p; rightNode.getLeftNode().setParentNode(node); //r.parent = p.parent; /** * 把rightNode的父结点设为node的父结点 */ rightNode.setParentNode(node.getParentNode()); /** * node的父结点为空 * 表明node是红黑树的根结点 */ //if (p.parent == null) if(node.getParentNode() == null) //root = r; this.setRootNode(rightNode); /** * node父结点的左子结点存储的值与node相同 * 表明node是父结点的左子结点 */ //else if (p.parent.left == p) else if(node.getParentNode().getLeftNode() == node) //p.parent.left = r; node.getParentNode().setLeftNode(rightNode); /** * node是父结点的右子结点 */ else //p.parent.right = r; node.getParentNode().setRightNode(rightNode); /** * rightNode的左子结点设为node */ //r.left = p; rightNode.setLeftNode(node); /** * node的父结点设为rightNode */ //p.parent = r; node.setParentNode(rightNode); } } /** * 围绕某个结点右旋转 * 原理同左旋转相同 * 只不过方向换了下 * @param node */ private void rotateRight(RBTreeNode<E>node){ //if (p != null) { if(node != null){ /** * 得到node的左子结点leftNode */ //Entry<K,V> l = p.left; RBTreeNode<E>leftNode = node.getLeftNode(); /** * 把node的左子结点设为leftNode的右子结点 */ //p.left = l.right; node.setLeftNode(leftNode.getRightNode()); /** * 如果leftNode的右子结点非空 * 那么把leftNode的右子结点的父结点设为node */ //if (l.right != null) l.right.parent = p; if(leftNode.getRightNode() != null) leftNode.getRightNode().setParentNode(node); /** * leftNode的父结点设为node的父结点 */ //l.parent = p.parent; leftNode.setParentNode(node.getParentNode()); /** * node为根结点 */ //if (p.parent == null) if(node.getParentNode() == null) //root = l; this.rootNode = leftNode; //else if (p.parent.right == p) else if(node.getParentNode().getRightNode() == node) //p.parent.right = l; node.getParentNode().setRightNode(leftNode); //else p.parent.left = l; else node.getParentNode().setLeftNode(leftNode); //l.right = p; leftNode.setRightNode(node); //p.parent = l; node.setParentNode(leftNode); } } public void insertNode(RBTreeNode<E> node) { if (node == null) return; if (node.getValue() == null) return; /** * rootnode为空, * 空的红黑树 */ if (this.getRootNode() == null) { rootNode = new RBTreeNode<E>(node.getValue()); return; } /** * rootnode非空 */ RBTreeNode<E> tempNode = this.rootNode; while (true) { /** * 红黑树中已经存在此结点 * 无须插入 * 直接返回 */ if (tempNode.compareTo(node) == 0) { return; }else if (tempNode.compareTo(node) > 0) { if (tempNode.getLeftNode() != null) { tempNode = tempNode.getLeftNode(); }else { tempNode.setLeftNode(node); node.setParentNode(tempNode); fixAfterInsertion(node); return; } }else { if (tempNode.getRightNode() != null) { tempNode = tempNode.getRightNode(); }else { tempNode.setRightNode(node); node.setParentNode(tempNode); fixAfterInsertion(node); return; } } } } private void fixAfterInsertion(RBTreeNode<E>node){ if(node == null) return; /** * node标记为红结点 */ //x.color = RED; node.setColor(RBTreeNode.RED); /** * while循环条件 * node非空 并且 * node非根结点 并且 * node的父结点的颜色为红色 */ //while (x != null && x != root && x.parent.color == RED) { while(node != null && ( node != rootNode) && node.getParentNode().getColor() == RBTreeNode.RED){ /** * node的父结点是node祖父结点的左子结点 */ //if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { if(parentOf(node) == leftOf(parentOf(parentOf(node)))){ /** * y是node祖父结点的右子结点 */ //Entry<K,V> y = rightOf(parentOf(parentOf(x))); RBTreeNode<E> y = rightOf(parentOf(parentOf(node))); /** * 如果y的颜色是红色 */ //if (colorOf(y) == RED) { if(colorOf(y) == RBTreeNode.RED){ /** * 把node父结点的颜色设为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node),RBTreeNode.BLACK); /** * 把y的颜色设为黑色 */ //setColor(y, BLACK); setColor(y,RBTreeNode.BLACK); /** * 把node祖父结点的颜色设为红色 */ //setColor(parentOf(parentOf(x)), RED); setColor(parentOf(parentOf(node)),RBTreeNode.RED); /** * node指向node的祖父结点 */ //x = parentOf(parentOf(x)); node = parentOf(parentOf(node)); } else { /** * 这块y的颜色是黑色 */ /** * 如果node是父结点的右子结点 */ //if (x == rightOf(parentOf(x))) { if(node == rightOf(parentOf(node))){ /** * node指向node的父结点 */ //x = parentOf(x); node = parentOf(node); /** * 围绕node进行左旋转 */ //rotateLeft(x); rotateLeft(node); } /** * 把node的父结点设置为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node),RBTreeNode.BLACK); /** * 把node的祖父结点设置为红色 */ //setColor(parentOf(parentOf(x)), RED); setColor(parentOf(parentOf(node)),RBTreeNode.RED); /** * 围绕node的祖父结点进行右旋转 */ //rotateRight(parentOf(parentOf(x))); rotateRight(parentOf(parentOf(node))); } /** * node的父结点是node祖父结点的右子结点 */ } else { /** * y指向node祖父结点的左子结点 */ //Entry<K,V> y = leftOf(parentOf(parentOf(x))); RBTreeNode<E> y = leftOf(parentOf(parentOf(node))); /** * 如果y的颜色是红色 */ //if (colorOf(y) == RED) { if(colorOf(y) == RBTreeNode.RED){ /** * 把node的父结点设为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node),RBTreeNode.BLACK); /** * 把y的颜色设为黑色 */ //setColor(y, BLACK); setColor(y,RBTreeNode.BLACK); /** * 把node的祖父结点设为红色 */ //setColor(parentOf(parentOf(x)), RED); setColor(parentOf(parentOf(node)),RBTreeNode.RED); /** * node结点指向其祖父结点 * 然后向上逐层调整 */ //x = parentOf(parentOf(x)); node = parentOf(parentOf(node)); } else { /** * node是node父结点的左子结点 */ //if (x == leftOf(parentOf(x))) { if(node == leftOf(parentOf(node))){ /** * node指向node的父结点 */ //x = parentOf(x); node = parentOf(node); /** * 围绕node进行右旋转 * 其实node已经是老node的父结点了 */ //rotateRight(x); rotateRight(node); } /** * 把node的父结点设为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node),RBTreeNode.BLACK); /** * 把node的祖父结点设为红色 */ //setColor(parentOf(parentOf(x)), RED); setColor(parentOf(parentOf(node)),RBTreeNode.RED); /** * 围绕node的祖父结点进行左旋转 */ //rotateLeft(parentOf(parentOf(x))); rotateLeft(parentOf(parentOf(node))); } } } /** * 把根结点设成黑色 */ //root.color = BLACK; setColor(rootNode,RBTreeNode.BLACK); } public void deleteNode(RBTreeNode<E> p) { //modCount++; //size--; // If strictly internal, copy successor's element to p and then make p // point to successor. /** * p的两个子结点都非空 */ //if (p.left != null && p.right != null) { if (p.getLeftNode() != null && p.getRightNode() != null) { //Entry<K,V> s = successor (p); RBTreeNode<E> s = successor(p); //p.key = s.key; p.setValue(s.getValue()); //p.value = s.value; p = s; } // p has 2 children // Start fixup at replacement node, if it exists. //Entry<K,V> replacement = (p.left != null ? p.left : p.right); RBTreeNode<E> replacement = (p.getLeftNode() != null ? p.getLeftNode() : p.getRightNode()); if (replacement != null) { // Link replacement to parent //replacement.parent = p.parent; replacement.setParentNode(p.getParentNode()); /** * p的父结点为空 * p是根结点 */ //if (p.parent == null) if (p.getParentNode() == null) //root = replacement; rootNode = replacement; /** * p是父结点的左子结点 */ //else if (p == p.parent.left) else if (p == p.getParentNode().getLeftNode()) //p.parent.left = replacement; p.getParentNode().setLeftNode(replacement); /** * p是父结点的右子结点 */ else //p.parent.right = replacement; p.getParentNode().setRightNode(replacement); /** * ok * 把p的左右子结点,父结点指针全部置空 * p被删除了 */ // Null out links so they are OK to use by fixAfterDeletion. //p.left = p.right = p.parent = null; p.setLeftNode(null); p.setRightNode(null); p.setParentNode(null); // Fix replacement //if (p.color == BLACK) if (p.getColor() == RBTreeNode.BLACK) fixAfterDeletion(replacement); //} else if (p.parent == null) { // return if we are the only node. } else if (p.getParentNode() == null) { //root = null; rootNode = null; } else { // No children. Use self as phantom replacement and unlink. /** * 在这个else里面 * replacement是null * 表明p的左右两个子结点都为空 */ //if (p.color == BLACK) if (p.getColor() == RBTreeNode.BLACK) fixAfterDeletion(p); //if (p.parent != null) { if (p.getParentNode() != null) { /** * p是p的父结点的左子结点 */ //if (p == p.parent.left) if (p == p.getParentNode().getLeftNode()) //p.parent.left = null; p.getParentNode().setLeftNode(null); /** * p是p的父结点的右子结点 */ //else if (p == p.parent.right) else if (p == p.getParentNode().getRightNode()) //p.parent.right = null; p.getParentNode().setRightNode(null); /** * 把p的父结点设为空 * 删除OK */ //p.parent = null; p.setParentNode(null); } } } //private void fixAfterDeletion(Entry<K,V> x) { private void fixAfterDeletion(RBTreeNode<E>node){ /** * 循环条件: * node不是根结点 * 而且 * node结点的颜色为黑色 */ //while (x != root && colorOf(x) == BLACK) { while(this.getRootNode() != node && colorOf(node) == RBTreeNode.BLACK){ /** * node是node父结点的左子结点 */ //if (x == leftOf(parentOf(x))) { if( node == leftOf(parentOf(node))){ /** * sib指向node父结点的右子结点 */ //Entry<K,V> sib = rightOf(parentOf(x)); RBTreeNode<E> sib = rightOf(parentOf(node)); /** * 参见colorOf(RBTreeNode<E>)方法实现 * 有对空值的判断 */ //if (colorOf(sib) == RED) { if(colorOf(sib) == RBTreeNode.RED){ /** * setColor()中也有对空值的判断 */ //setColor(sib, BLACK); setColor(sib, RBTreeNode.BLACK); /** * 把node的父结点设为红色 */ //setColor(parentOf(x), RED); setColor(parentOf(node), RBTreeNode.RED); /** * 围绕node的父结点进行左旋转 */ //rotateLeft(parentOf(x)); rotateLeft(parentOf(node)); /** * sib指向node父结点的右子结点 */ //sib = rightOf(parentOf(x)); sib = rightOf(parentOf(node)); } /** * 如果sib的两个子结点都是黑色 */ //if (colorOf(leftOf(sib)) == BLACK && if(colorOf(leftOf(sib)) == RBTreeNode.BLACK && //colorOf(rightOf(sib)) == BLACK) { colorOf(rightOf(sib)) == RBTreeNode.BLACK) { /** * 把sib设为红色 */ //setColor(sib, RED); setColor(sib, RBTreeNode.RED); /** * node指向它的父结点 */ //x = parentOf(x); node = parentOf(node); } else {//这个else表示sib的两个子结点并非都是黑色,一红一黑或都是红色 /** * 如果sib的右子结点是黑色 * 那它的左子结点肯定是红色 */ //if (colorOf(rightOf(sib)) == BLACK) { if(colorOf(rightOf(sib)) == RBTreeNode.BLACK) { /** * 把sib的左子结点设为黑色 */ //setColor(leftOf(sib), BLACK); setColor(leftOf(sib), RBTreeNode.BLACK); /** * 把sib的颜色设为黑色 */ //setColor(sib, RED); setColor(sib, RBTreeNode.RED); /** * 围绕sib进行右旋转 */ //rotateRight(sib); rotateRight(sib); /** * sib指向node父结点的右子结点 */ //sib = rightOf(parentOf(x)); sib = rightOf(parentOf(node)); } /** * 把sib的颜色设为node父结点的颜色 */ //setColor(sib, colorOf(parentOf(x))); setColor(sib, colorOf(parentOf(node))); /** * 把node父结点设为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node), RBTreeNode.BLACK); /** * 把sib右子结点的颜色设为黑色 */ //setColor(rightOf(sib), BLACK); setColor(rightOf(sib), RBTreeNode.BLACK); /** * 围绕node的父结点进行左旋转 */ //rotateLeft(parentOf(x)); rotateLeft(parentOf(node)); /** * node结点指向红黑树的根结点 */ //x = root; node = rootNode; } } else { // symmetric /** * sib指向node父结点的左子结点 */ //Entry<K,V> sib = leftOf(parentOf(x)); RBTreeNode<E> sib = leftOf(parentOf(node)); /** * 如果sib的颜色是红色 */ //if (colorOf(sib) == RED) { if(colorOf(sib) == RBTreeNode.RED) { /** * 把sib的颜色设为黑色 */ //setColor(sib, BLACK); setColor(sib, RBTreeNode.BLACK); /** * 把node父结点的颜色设为红色 */ //setColor(parentOf(x), RED); setColor(parentOf(node), RBTreeNode.RED); /** * 围绕node的父结点进行右旋转 */ //rotateRight(parentOf(x)); rotateRight(parentOf(node)); /** * sib指向node父结点的左子结点 */ //sib = leftOf(parentOf(x)); sib = leftOf(parentOf(node)); } /** * 如果sib的两个子结点都是黑色 */ //if (colorOf(rightOf(sib)) == BLACK && if (colorOf(rightOf(sib)) == RBTreeNode.BLACK && //colorOf(leftOf(sib)) == BLACK) { colorOf(leftOf(sib)) == RBTreeNode.BLACK) { /** * 把sib的颜色设为红色 */ //setColor(sib, RED); setColor(sib, RBTreeNode.RED); /** * node指向node的父结点 */ //x = parentOf(x); node = parentOf(node); } else { /** * 如果sib的左子结点是黑色 */ //if (colorOf(leftOf(sib)) == BLACK) { if (colorOf(leftOf(sib)) == RBTreeNode.BLACK) { /** * 把sib的右子结点设为黑色 */ //setColor(rightOf(sib), BLACK); setColor(rightOf(sib), RBTreeNode.BLACK); /** * 把sib的颜色设为红色 */ //setColor(sib, RED); setColor(sib, RBTreeNode.RED); /** * 围绕sib进行左旋转 */ rotateLeft(sib); /** * sib指向node父结点的左子结点 */ //sib = leftOf(parentOf(x)); sib = leftOf(parentOf(node)); } /** * 把sib的颜色设为node父结点的颜色 */ //setColor(sib, colorOf(parentOf(x))); setColor(sib, colorOf(parentOf(node))); /** * 把node父结点的颜色设为黑色 */ //setColor(parentOf(x), BLACK); setColor(parentOf(node), RBTreeNode.BLACK); /** * 把sib左子结点的颜色设为黑色 */ //setColor(leftOf(sib), BLACK); setColor(leftOf(sib), RBTreeNode.BLACK); /** * 围绕node的父结点进行右旋转 */ //rotateRight(parentOf(x)); rotateRight(parentOf(node)); //x = root; node = rootNode; } } } //setColor(x, BLACK); setColor(node, RBTreeNode.BLACK); } public static void main(String []args){ RBTree<String> r = new RBTree<String>(); r.insertNode(new RBTreeNode<String>("a")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("b")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("c")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("d")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("e")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("f")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("g")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("h")); System.out.println(r.getRootNode().getValue()); r.insertNode(new RBTreeNode<String>("i")); System.out.println(r.getRootNode().getValue()); } }
转自:
http://blog.163.com/fulei.20030727@126/blog/static/300662212007112205334389/
- 红黑树的Java实现
- 红黑树的JAVA实现
- 红黑树的java实现
- 红黑树的Java实现
- 红黑树的Java实现
- 红黑树的java实现
- 红黑树的java实现
- 红黑树Java的实现
- 红黑树的Java实现
- 红黑树算法的Java实现
- java TreeMap红黑树的实现
- JAVA实现的时钟实现
- java实现红黑树的插入与调整
- 红黑树(五)之 Java的实现
- java实现红黑树的插入节点
- 【Java】Java中多态的实现
- “网络蚂蚁”的Java实现
- Java的MD5实现
- C语言之第三课:C语言的基本元素
- 找出数组中出现次数超过一半的数
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- javascript学习 - 字符串切割查找
- $.post() $.get() $.getJSON() | XML数据的处理
- 红黑树的Java实现
- eclipse安装svn和maven插件
- mac 下.svn 文件删除
- php namespace-命名空间
- MRC下delegate野指针问题
- appcan+在线打包完成如何安装到手机上
- 一个整数的每个数位都平方后求和,又得到一个整数,我们称这个整数为:位平方和。
- KafkaSpout的核心逻辑都是由PartitionManager来实现的。
- 第六周——项目四成员函数,友元函数,一般函数的区别