红黑树啊,怎么这么难呢?哎,还得继续研究,目前只是完成了红黑树的添加,删除还没有完成(自己汗一个)。
package com.au.algorithm;
import java.util.ArrayList;
import java.util.List;
/**
* 红黑树的五个性质:
*
* 1)每个结点要么是红的,要么是黑的。
* 2)根结点是黑的。
* 3)每个叶结点,即空结点(NIL)是黑的。
* 4)如果一个结点是红的,那么它的俩个儿子都是黑的。
* 5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。
*
*
* @author fuyouming
*
* @param <E>
*/
public class RBTree<E extends Comparable<E>> {
private Node<E> root;
/**
* 在对红黑树进行插入操作时,我们一般总是插入红色的结点,因为这样可以在插入过程中尽量避免对树的调整。
* 如果插入的结点是根结点,性质2会被破坏,如果插入结点的父结点是红色,则会破坏性质4。
* 因此,总而言之,插入一个红色结点只会破坏性质2或性质4。
*
*
* @param e
*/
public void insert(E e) {
System.out.println("====== 添加节点 " + e + "======");
if (root == null) {
root = new Node<E>(null, e, Color.BLACK);
} else {
Node<E> current = root;
Node<E> parent = null;
int negative = 0;
while (current != null) {
negative = e.compareTo(current.key);
parent = current;
if (negative < 0) {
current = current.left;
} else if (negative > 0) {
current = current.right;
} else {
return;
}
}
current = new Node<E>(parent, e, Color.RED);
if (negative < 0) {
parent.left = current;
} else {
parent.right = current;
}
insertFixup(current);
}
}
public boolean remove(E e){
if (root == null)
return false;
Node<E> current = root;
int negative = 0;
while (current != null) {
negative = e.compareTo(current.key);
if (negative < 0) {
current = current.left;
} else if (negative > 0) {
current = current.right;
} else {
break;
}
}
if(current != null){
if (current.right != null) {
Node<E> newCurrent = current.right;
while (newCurrent.left != null) {
newCurrent = newCurrent.left;
}
current.key = newCurrent.key;
current = newCurrent;
}
System.out.println("====== 删除节点 " + e + "(" + (current == null ? ""
: current.key) + ")======");
Node<E> brother, parent = current.parent, rightChild = current.right;
if (current == parent.left) {
parent.left = rightChild;
brother = parent.right;
} else {
parent.right = rightChild;
brother = parent.left;
}
if (current.color == Color.BLACK) {
if (rightChild != null) {
rightChild.parent = parent;
// 当删除的节点有一个红色的孩子
if (rightChild.color == Color.RED) {
rightChild.color = Color.BLACK;
}
} else {
if (brother != null) {
if (brother.color == Color.RED) {
// 父=>红,兄=>黑
parent.color = Color.RED;
brother.color = Color.BLACK;
if (brother == parent.right) {
rotateLeft(brother);// 左旋转父节点
} else {
if (brother.left != null)
rotateRight(brother.left);// 右旋转父节点
}
} else {
if (brother.left != null
&& brother.left.color == Color.RED) {
// 侄=>父色,父=>黑
brother.color = parent.color;
brother.left.color = parent.color = Color.BLACK;
if (brother == parent.right) {
rotateLeft(brother.left);// 左旋转父节点
rotateRight(brother);
} else {
rotateRight(brother.left);// 右旋转父节点
}
} else if (brother.right != null
&& brother.right.color == Color.RED) {
// 兄=>父色,父=>黑,侄=>黑,(子=>黑)
brother.color = brother.parent.color;
parent.color = brother.right.color = Color.BLACK;
if (brother == parent.right) {
rotateRight(brother.right);// 右旋转父节点
} else {
rotateLeft(brother.right);// 左旋转父节点
rotateRight(brother);
}
} else {
//兄=>红,子=黑,红父=>黑, 往上遍历(黑父)
brother.color = Color.RED;
while(parent != null && parent.color == Color.BLACK){
parent = parent.parent;
}
if(parent != null && parent.color == Color.RED){
parent.color = Color.BLACK;
}
}
}
}
}
}
}
return false;
}
/**
* 红黑树的所有插入情况有以下五种:
*
* 情况1:插入的是根结点。
* 分析:原树是空树,此情况只会违反性质2。
*
* 情况2:插入的结点的父结点是黑色。
* 分析:此不会违反性质2和性质4,红黑树没有被破坏。
*
* 情况3:当前结点的父结点是红色且祖父结点的另一个子结点(叔叔结点)是红色。
* 分析:此情况违反了性质4。
*
* 情况4:当前节点的父节点是红色,叔叔节点是黑色或NIL,当前节点是其父节点的右子。
* 分析:此情况违反了性质4。
*
* 情况5:当前节点的父节点是红色,叔叔节点是黑色或NIL,当前节点是其父节点的左子。
* 分析:此情况违反了性质4。
*/
private void insertFixup(Node<E> current) {
Node<E> grandparent, parent, uncle;
// 当有两个相连的节点都是红色的时候,违反了红黑树的性质,所以必须要调整
while ((parent = current.parent) != null && parent.color == Color.RED
&& current.color == Color.RED) {
grandparent = parent.parent;
uncle = parent == grandparent.left ? grandparent.right
: grandparent.left;
if (uncle != null && uncle.color == Color.RED) {
// 父=>黑,叔=>黑,祖=>红,祖为新节点开始
uncle.color = parent.color = Color.BLACK;
grandparent.color = Color.RED;
current = grandparent;
} else {
grandparent.color = Color.RED;// 祖=>红
if ((parent == grandparent.left && current == parent.left)
|| (parent == grandparent.right && current == parent.right)) {
parent.color = Color.BLACK;// 父=>黑
// 父=>黑,祖=>红,祖父右旋转
rotateRight(current);
} else {
current.color = Color.BLACK;// 新=>黑
// 新=>黑,祖=>红,父左旋转;祖右旋转
rotateLeft(current);
rotateRight(parent);
}
current = parent;// 以父节点为新的当前节点
}
}
root.color = Color.BLACK;// 根节点永远都是黑的
}
/**
* 左旋:父节点和孩子节点交换角色
*/
private void rotateLeft(Node<E> current) {
System.out.println("左旋:" + current.key);
Node<E> parent = current.parent, grandparent = parent.parent, child = null;
if (current == parent.right) {
child = current.left;
parent.right = child;
current.left = parent;
} else {
child = current.right;
parent.left = child;
current.right = parent;
}
if (child != null)
child.parent = parent;
if (parent == grandparent.left) {
grandparent.left = current;
} else {
grandparent.right = current;
}
current.parent = grandparent;
parent.parent = current;
}
/**
* 右旋:祖父节点和兄弟节点交换角色
*/
private void rotateRight(Node<E> current) {
System.out.println("右旋:" + current.key);
Node<E> parent = current.parent, grandparent = parent.parent, brother = null;
if (current == parent.left) {
brother = parent.right;
parent.right = grandparent;
} else {
brother = parent.left;
parent.left = grandparent;
}
if (parent == grandparent.left)
grandparent.left = brother;
else
grandparent.right = brother;
if (brother != null)
brother.parent = grandparent;
if (grandparent.parent != null) {
if (grandparent.parent.left == grandparent) {
grandparent.parent.left = parent;
} else {
grandparent.parent.right = parent;
}
} else {
root = parent;
}
parent.parent = grandparent.parent;
grandparent.parent = parent;
}
public void print() {
List<Node> list = new ArrayList<Node>();
if(this.root == null) return;
list.add(this.root);
while (!list.isEmpty()) {
List<Node> l = new ArrayList<Node>();
for (Node n : list) {
System.out.print(n.key
//+ "("
//+ (n.color == Color.RED ? "红" : "黑")
//+ ")["
+"["
+ (n.left != null ? n.left.key + "("
+ (n.left.color == Color.RED ? "红" : "黑") + ")"
: "无")
+ " "
+ (n.right != null ? n.right.key + "("
+ (n.right.color == Color.RED ? "红" : "黑")
+ ")" : "无") + "] ");
if (n.left != null) {
l.add(n.left);
}
if (n.right != null) {
l.add(n.right);
}
}
System.out.print("\r");
list = l;
}
}
static enum Color {
BLACK, RED
}
static class Node<E extends Comparable<E>> {
E key;
Node<E> left, right;
Node<E> parent;
Color color;
Node(Node<E> parent, E key, Color color) {
this.key = key;
this.color = color;
this.parent = parent;
this.left = null;
this.right = null;
}
}
public static void main(String[] args) {
RBTree<Integer> tree = new RBTree<Integer>();
int[] intArr = new int[] { 12, 1, 9, 2, 0, 11, 7, 19, 4, 15, 18, 5, 14, 13, 10, 16, 6, 3, 8, 17 };// 情况3
for (int i = 0; i < intArr.length; i++) {
tree.insert(intArr[i]);
}
tree.print();
for (int i = 0; i < intArr.length-1; i++) {
tree.remove(intArr[i]);
tree.print();
}
}
}