红黑树(Red Black Tree) 是一种自平衡二叉查找树,红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除。
红黑树的性质:
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
红黑树通过旋转来保持它的基本特性达到平衡,旋转的操作有左旋和右旋。
以下是用Java实现的红黑树代码:
package tree;
public class RBTree {
enum CORLOR{
RED,BLACK;
}
class RBTNode {
CORLOR color;
int key;
RBTNode left;
RBTNode right;
RBTNode parent;
public RBTNode(CORLOR color, int key, RBTNode left, RBTNode right, RBTNode parent) {
this.color = color;
this.key = key;
this.left = left;
this.right = right;
this.parent = parent;
}
}
private RBTNode root;
public RBTNode getRoot() {
return root;
}
public void setRoot(RBTNode root) {
this.root = root;
}
private RBTNode parentOf(RBTNode node) {
return node != null ? node.parent : null;
}
private boolean isRed(RBTNode node) {
if(node != null && node.color == CORLOR.RED) {
return true;
}
return false;
}
private boolean isBlack(RBTNode node) {
if(node != null && node.color == CORLOR.BLACK) {
return true;
}
return false;
}
//左旋操作
private void leftRotate(RBTNode x) {
RBTNode y = x.right; //把x的右孩子赋给y
x.right = y.left; //把y的左孩子即原x的右孩子的左孩子设为x的右孩子
if(y.left != null) {
y.left.parent = x; //如果y的左孩子非空,把x设为y的左孩子的父结点
}
y.parent = x.parent;
if(x.parent == null) {
this.root = y; //如果x的父结点为空,则将y设为根结点
}
else {
if(x.parent.left == x) {
x.parent.left = y; //如果x是它父结点的左孩子,则将y设为x的父结点的左孩子
}
else {
x.parent.right = y; // 如果x是它父结点的右孩子,则将y设为设为x父结点的右孩子
}
}
y.left = x; // 将x设为y的左孩子
x.parent = y;
}
//右旋操作
private void rightRotate(RBTNode y) {
RBTNode x = y.left;
y.left = x.right;
if(x.right != null) {
x.right.parent = y;
}
x.parent = y.parent;
if(y.parent == null) {
this.root = 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 node) {
RBTNode parent, gparent;
while (((parent = parentOf(node))!=null) && isRed(parent)) {
gparent = parentOf(parent);
if (parent == gparent.left) {
RBTNode uncle = gparent.right;
if ((uncle!=null) && isRed(uncle)) {
uncle.color = CORLOR.BLACK;
parent.color = CORLOR.BLACK;
gparent.color = CORLOR.RED;
node = gparent;
continue;
}
if (parent.right == node) {
RBTNode tmp;
leftRotate(parent);
tmp = parent;
parent = node;
node = tmp;
}
parent.color = CORLOR.BLACK;
gparent.color = CORLOR.RED;
rightRotate(gparent);
} else {
RBTNode uncle = gparent.left;
if ((uncle!=null) && isRed(uncle)) {
uncle.color = CORLOR.BLACK;
parent.color = CORLOR.BLACK;
gparent.color = CORLOR.RED;
node = gparent;
continue;
}
if (parent.left == node) {
RBTNode tmp;
rightRotate(parent);
tmp = parent;
parent = node;
node = tmp;
}
parent.color = CORLOR.BLACK;
gparent.color = CORLOR.RED;
leftRotate(gparent);
}
}
this.root.color = CORLOR.BLACK;
}
private void insert(RBTNode node) {
RBTNode y = null;
RBTNode x = this.root;
while ( x != null ) {
y = x;
if(node.key < x.key) {
x = x.left;
}
else {
x = x.right;
}
}
node.parent = y;
if(y != null) {
if(node.key < y.key) {
y.left = node;
}
else {
y.right = node;
}
}
else {
this.root = node;
}
node.color = CORLOR.RED;
insertFixUp(node);
}
public void insert(int key) {
RBTNode node = new RBTNode(CORLOR.BLACK, key, null, null, null);
if(node != null) {
insert(node);
}
}
//删除修正函数
private void removeFixUp(RBTNode node, RBTNode parent) {
RBTNode other;
while( (node == null || isBlack(node)) && node != this.root) {
if(parent.left == node) {
other = parent.right;
if( isRed(other) ) {
other.color = CORLOR.BLACK;
parent.color = CORLOR.RED;
leftRotate(parent);
other = parent.right;
}
if((other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
other.color = CORLOR.RED;
node = parent;
parent = parentOf(node);
}
else {
if(other.right == null || isBlack(other.right)) {
other.left.color = CORLOR.BLACK;
other.color = CORLOR.RED;
rightRotate(other);
other = parent.right;
}
other.color = parent.color;
parent.color = CORLOR.BLACK;
other.right.color = CORLOR.BLACK;
leftRotate(parent);
node = this.root;
break;
}
}
else {
other = parent.left;
if(isRed(other)) {
other.color = CORLOR.BLACK;
parent.color = CORLOR.RED;
rightRotate(parent);
other = parent.left;
}
if( (other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
other.color = CORLOR.RED;
node = parent;
parent = parentOf(node);
}
else {
if(other.left == null || isBlack(other.left) ) {
other.right.color = CORLOR.BLACK;
other.color = CORLOR.RED;
leftRotate(other);
other = parent.left;
}
other.color = parent.color;
parent.color = CORLOR.BLACK;
other.left.color = CORLOR.BLACK;
rightRotate(parent);
node = this.root;
break;
}
}
}
if(node != null) {
node.color = CORLOR.BLACK;
}
}
//删除结点
private void remove(RBTNode node) {
RBTNode child,parent;
CORLOR color;
if( node.left != null && node.right != null) {
RBTNode 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.root = replace;
}
child = replace.right;
parent = parentOf(replace);
color = replace.color;
if(parent == node) {
parent = replace;
}
else {
if(child != null) {
child.parent = parent;
}
parent.left = child;
replace.right = node.right;
node.right.parent = replace;
}
replace.parent = node.parent;
replace.color = node.color;
replace.left = node.left;
node.left.parent = replace;
if(color == CORLOR.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.root = child;
}
if(color == CORLOR.BLACK) {
removeFixUp(child, parent);
}
node = null;
}
public RBTNode search(RBTNode x,int key) {
if(x == null) {
return x;
}
if(x.key > key) {
return search(x.left,key);
}
else if(x.key < key) {
return search(x.right,key);
}
else
return x;
}
public RBTNode search(int key) {
return search(this.root,key);
}
public void remove(int key) {
RBTNode node;
if( (node = search(root,key) ) != null)
remove(node);
}
//中序遍历
private void inOrder(RBTNode tree) {
if(tree != null) {
inOrder(tree.left);
System.out.print(tree.key+" ");
inOrder(tree.right);
}
}
//先序遍历
private void preOrder(RBTNode tree) {
if(tree != null) {
System.out.print(tree.key+" ");
preOrder(tree.left);
preOrder(tree.right);
}
}
//后序遍历
private void postOrder(RBTNode tree) {
if(tree != null) {
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.key+" ");
}
}
public static void main(String[] args) {
RBTree tree = new RBTree();
tree.insert(10);
tree.insert(40);
tree.insert(30);
tree.insert(60);
tree.insert(90);
tree.insert(70);
tree.insert(20);
tree.insert(50);
tree.insert(80);
//中序遍历
System.out.println("中序遍历:");
tree.inOrder(tree.root);
System.out.println("\n先序遍历:");
tree.preOrder(tree.root);
System.out.println("\n后序遍历:");
tree.postOrder(tree.root);
}
}
以下是测试结果: