package datastructure;
*
* 红黑树的数据结构
*
* @param <T>
*/
public class RBTree<T extends Comparable<T>> {
private RBTNode<T> mRoot;
private static final boolean RED = false;
private static final boolean BLACK = true;
public class RBTNode<T extends Comparable<T>> {
boolean color;
T key;
RBTNode<T> left;
RBTNode<T> right;
RBTNode<T> parent;
public RBTNode(boolean color, T key, RBTNode<T> left, RBTNode<T> right, RBTNode<T> parent) {
super();
this.color = color;
this.key = key;
this.left = left;
this.right = right;
this.parent = parent;
}
public T getkey() {
return key;
}
public String toString() {
return "" + key + (this.color == RED ? "(R)" : "B");
}
}
public RBTree() {
mRoot = null;
}
private RBTNode<T> parentOf(RBTNode<T> node) {
return node != null ? node.parent : null;
}
private boolean colorOf(RBTNode<T> node) {
return node != null ? node.color : BLACK;
}
private boolean isRed(RBTNode<T> node) {
return ((node != null) && (node.color == RED)) ? true : false;
}
private boolean isBlack(RBTNode<T> node) {
return isRed(node);
}
private void setRed(RBTNode<T> node) {
if (node != null) {
node.color = RED;
}
}
private void setBlack(RBTNode<T> node) {
if (node != null) {
node.color = BLACK;
}
}
private void setParent(RBTNode<T> node, RBTNode<T> parent) {
if (node != null) {
node.parent = parent;
}
}
private void setColor(RBTNode<T> node, boolean color) {
if (node != null) {
node.color = color;
}
}
* 前序遍历红黑树
*
* @param tree
*/
private void preOrder(RBTNode<T> tree) {
if (tree != null) {
System.out.print(tree.key + " ");
preOrder(tree.left);
preOrder(tree.right);
}
}
public void preOrder() {
preOrder(mRoot);
}
* 中序遍历红黑树
*
* @param tree
*/
private void inOrder(RBTNode<T> tree) {
if (tree != null) {
inOrder(tree.left);
System.out.print(tree.key + " ");
inOrder(tree.right);
}
}
public void inOrder() {
inOrder(mRoot);
}
* 后序遍历红黑树
*
* @param tree
*/
private void postOrder(RBTNode<T> tree) {
if (tree != null) {
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.key + " ");
}
}
public void postOrder() {
postOrder(mRoot);
}
* (递归实现)查找"红黑树x"中键值为key的节点
*
* @param x
* @param key
* @return
*/
private RBTNode<T> search(RBTNode<T> x, T key) {
if (x == null) {
return x;
}
int cmp = key.compareTo(x.key);
if (cmp < 0) {
return search(x.left, key);
} else if (cmp > 0) {
return search(x.right, key);
} else {
return x;
}
}
public RBTNode<T> search(T key) {
return search(mRoot, key);
}
* (非递归实现)查找"红黑树x"中键值为key的节点
*
* @param x
* @param key
* @return
*/
private RBTNode<T> iterativeSearch(RBTNode<T> x, T key) {
while (x != null) {
int cmp = key.compareTo(x.key);
if (cmp < 0) {
x = x.left;
} else if (cmp > 0) {
x = x.right;
} else {
return x;
}
}
return x;
}
public RBTNode<T> iterativeSearch(T key) {
return iterativeSearch(key);
}
* 查找最小结点:返回tree为根结点的红黑树的最小结点。
*
* @param tree
* @return
*/
private RBTNode<T> minimum(RBTNode<T> tree) {
if (tree == null) {
return null;
}
while (tree.left != null) {
tree = tree.left;
}
return tree;
}
public T minimum() {
RBTNode<T> p = minimum(mRoot);
if (p != null) {
return p.key;
}
return null;
}
* 查找最大结点:返回tree为根结点的红黑树的最大结点。
*
* @param tree
* @return
*/
private RBTNode<T> maximum(RBTNode<T> tree) {
if (tree == null) {
return null;
}
while (tree.right != null) {
tree = tree.right;
}
return tree;
}
public T maximum() {
RBTNode<T> p = maximum(mRoot);
if (p != null) {
return p.key;
}
return null;
}
* 找结点(x)的后继结点。即,查找"红黑树中数据值大于该结点"的"最小结点"。
*
* @param x
* @return
*/
public RBTNode<T> successor(RBTNode<T> x) {
if (x.right != null) {
return minimum(x.right);
}
RBTNode<T> y = x.parent;
while ((y != null) && (x == y.right)) {
x = y;
y = y.parent;
}
return y;
}
* 找结点(x)的前驱结点。即,查找"红黑树中数据值小于该结点"的"最大结点"。
*
* @param x
* @return
*/
public RBTNode<T> predecessor(RBTNode<T> x) {
if (x.left != null)
return maximum(x.left);
RBTNode<T> y = x.parent;
while ((y != null) && (x == y.left)) {
x = y;
y = y.parent;
}
return y;
}
*
* 左旋示意图(对节点x进行左旋):
* px px
* / /
* x y
* / \ --(左旋)-. / \ #
* lx y x ry
* / \ / \
* ly ry lx ly
*
*
*/
private void leftRotate(RBTNode<T> x) {
RBTNode<T> y = x.right;
x.right = y.left;
if (y.left != null)
y.left.parent = x;
y.parent = x.parent;
if (x.parent == null) {
this.mRoot = y;
} else {
if (x.parent.left == x)
x.parent.left = y;
else
x.parent.right = y;
}
y.left = x;
x.parent = y;
}
* 对红黑树的节点(y)进行右旋转
*
* 右旋示意图(对节点y进行左旋):
* py py
* / /
* y x
* / \ --(右旋)-. / \ #
* x ry lx y
* / \ / \ #
* lx rx rx ry
*
*/
private void rightRotate(RBTNode<T> y) {
RBTNode<T> x = y.left;
y.left = x.right;
if (x.right != null)
x.right.parent = y;
x.parent = y.parent;
if (y.parent == null) {
this.mRoot = x;
} else {
if (y == y.parent.right)
y.parent.right = x;
else
y.parent.left = x;
}
x.right = y;
y.parent = x;
}
private void insertFixUp(RBTNode<T> node) {
RBTNode<T> parent, gparent;
while (((parent = parentOf(node)) != null) && isRed(parent)) {
gparent = parentOf(parent);
if (parent == gparent.left) {
RBTNode<T> uncle = gparent.right;
if ((uncle != null) && isRed(uncle)) {
setBlack(uncle);
setBlack(parent);
setRed(gparent);
node = gparent;
continue;
}
if (parent.right == node) {
RBTNode<T> tmp;
leftRotate(parent);
tmp = parent;
parent = node;
node = tmp;
}
setBlack(parent);
setRed(gparent);
rightRotate(gparent);
} else {
RBTNode<T> uncle = gparent.left;
if ((uncle != null) && isRed(uncle)) {
setBlack(uncle);
setBlack(parent);
setRed(gparent);
node = gparent;
continue;
}
if (parent.left == node) {
RBTNode<T> tmp;
rightRotate(parent);
tmp = parent;
parent = node;
node = tmp;
}
setBlack(parent);
setRed(gparent);
leftRotate(gparent);
}
}
setBlack(this.mRoot);
}
* 将结点插入到红黑树中
*
* 参数说明: node 插入的结点 // 对应《算法导论》中的node
*/
private void insert(RBTNode<T> node) {
int cmp;
RBTNode<T> y = null;
RBTNode<T> x = this.mRoot;
while (x != null) {
y = x;
cmp = node.key.compareTo(x.key);
if (cmp < 0)
x = x.left;
else
x = x.right;
}
node.parent = y;
if (y != null) {
cmp = node.key.compareTo(y.key);
if (cmp < 0)
y.left = node;
else
y.right = node;
} else {
this.mRoot = node;
}
node.color = RED;
insertFixUp(node);
}
* 新建结点(key),并将其插入到红黑树中
*
* 参数说明: key 插入结点的键值
*/
public void insert(T key) {
RBTNode<T> node = new RBTNode<T>(BLACK, key, null, null, null);
if (node != null)
insert(node);
}
* 红黑树删除修正函数
*
* 在从红黑树中删除插入节点之后(红黑树失去平衡),再调用该函数; 目的是将它重新塑造成一颗红黑树。
*
* 参数说明: node 待修正的节点
*/
private void removeFixUp(RBTNode<T> node, RBTNode<T> parent) {
RBTNode<T> other;
while ((node == null || isBlack(node)) && (node != this.mRoot)) {
if (parent.left == node) {
other = parent.right;
if (isRed(other)) {
setBlack(other);
setRed(parent);
leftRotate(parent);
other = parent.right;
}
if ((other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
setRed(other);
node = parent;
parent = parentOf(node);
} else {
if (other.right == null || isBlack(other.right)) {
setBlack(other.left);
setRed(other);
rightRotate(other);
other = parent.right;
}
setColor(other, colorOf(parent));
setBlack(parent);
setBlack(other.right);
leftRotate(parent);
node = this.mRoot;
break;
}
} else {
other = parent.left;
if (isRed(other)) {
setBlack(other);
setRed(parent);
rightRotate(parent);
other = parent.left;
}
if ((other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
setRed(other);
node = parent;
parent = parentOf(node);
} else {
if (other.left == null || isBlack(other.left)) {
setBlack(other.right);
setRed(other);
leftRotate(other);
other = parent.left;
}
setColor(other, colorOf(parent));
setBlack(parent);
setBlack(other.left);
rightRotate(parent);
node = this.mRoot;
break;
}
}
}
if (node != null)
setBlack(node);
}
* 删除结点(node),并返回被删除的结点
*
* 参数说明: node 删除的结点
*/
private void remove(RBTNode<T> node) {
RBTNode<T> child, parent;
boolean color;
if ((node.left != null) && (node.right != null)) {
RBTNode<T> replace = node;
replace = replace.right;
while (replace.left != null)
replace = replace.left;
if (parentOf(node) != null) {
if (parentOf(node).left == node)
parentOf(node).left = replace;
else
parentOf(node).right = replace;
} else {
this.mRoot = replace;
}
child = replace.right;
parent = parentOf(replace);
color = colorOf(replace);
if (parent == node) {
parent = replace;
} else {
if (child != null)
setParent(child, parent);
parent.left = child;
replace.right = node.right;
setParent(node.right, replace);
}
replace.parent = node.parent;
replace.color = node.color;
replace.left = node.left;
node.left.parent = replace;
if (color == BLACK)
removeFixUp(child, parent);
node = null;
return;
}
if (node.left != null) {
child = node.left;
} else {
child = node.right;
}
parent = node.parent;
color = node.color;
if (child != null)
child.parent = parent;
if (parent != null) {
if (parent.left == node)
parent.left = child;
else
parent.right = child;
} else {
this.mRoot = child;
}
if (color == BLACK)
removeFixUp(child, parent);
node = null;
}
* 删除结点(z),并返回被删除的结点
*
* 参数说明: tree 红黑树的根结点 z 删除的结点
*/
public void remove(T key) {
RBTNode<T> node;
if ((node = search(mRoot, key)) != null)
remove(node);
}
* 销毁红黑树
*/
private void destroy(RBTNode<T> tree) {
if (tree == null)
return;
if (tree.left != null)
destroy(tree.left);
if (tree.right != null)
destroy(tree.right);
tree = null;
}
public void clear() {
destroy(mRoot);
mRoot = null;
}
* 打印"红黑树"
*
* key -- 节点的键值 direction -- 0,表示该节点是根节点; -1,表示该节点是它的父结点的左孩子;
* 1,表示该节点是它的父结点的右孩子。
*/
private void print(RBTNode<T> tree, T key, int direction) {
if (tree != null) {
if (direction == 0)
System.out.printf("%2d(B) is root\n", tree.key);
else
System.out.printf("%2d(%s) is %2d's %6s child\n", tree.key, isRed(tree) ? "R" : "B", key,
direction == 1 ? "right" : "left");
print(tree.left, tree.key, -1);
print(tree.right, tree.key, 1);
}
}
public void print() {
if (mRoot != null)
print(mRoot, mRoot.key, 0);
}
}