经过几个星期的努力,红黑树终于弄清楚了。
先附上代码,然后贴上自己的分析图
package Alg;
public class RBTreeNode {
public enum Color {Red , Black };
private RBTreeNode leftChild = null;
private RBTreeNode rightChild = null;
private RBTreeNode parent = null;
private int value = Integer.MIN_VALUE;
private Color color = Color.Red;
private RBTreeNode(int val) {
this.setValue(val);
}
public static RBTreeNode createNode(int val) {
return new RBTreeNode(val);
}
public RBTreeNode getSibling() {
RBTreeNode p = this.parent;
if (p == null)
return null;
if (p.getLeftChild() == this)
return p.getRightChild();
return p.getLeftChild();
}
public boolean isRoot() {
if (this.parent == null)
return true;
return false;
}
public boolean isLeaf() {
if (this.getLeftChild() == null && this.getRightChild() == null)
return true;
return false;
}
public RBTreeNode getLeftChild() {
return leftChild;
}
public void setLeftChild(RBTreeNode leftChild) {
this.leftChild = leftChild;
}
public RBTreeNode getRightChild() {
return rightChild;
}
public void setRightChild(RBTreeNode rightChild) {
this.rightChild = rightChild;
}
public RBTreeNode getParent() {
return parent;
}
public void setParent(RBTreeNode parent) {
this.parent = parent;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
package Alg;
import Alg.RBTreeNode.Color;
public class RBTree {
public enum MatchType {E, GE, LE};
private RBTreeNode root = null;
private int count = 0;
public RBTreeNode search(int val, MatchType matchType) {
RBTreeNode n = search(val);
if (n == null)
return null;
if (n.getValue() == val)
return n;
switch (matchType) {
case LE:
if (n.getValue() < val)
return n;
return getLittleSmaller(n);
case GE:
if (n.getValue() > val)
return n;
return getLittleBigger(n);
default:
break;
}
return null;
}
public void insert(int val) throws Exception {
if (root == null) {
root = RBTreeNode.createNode(val);
count++;
root.setColor(RBTreeNode.Color.Black);
return;
}
RBTreeNode sNode = search(val);
if (sNode.getValue() == val)
return;
RBTreeNode x = RBTreeNode.createNode(val);
if (sNode.getValue() > val)
sNode.setLeftChild(x);
else
sNode.setRightChild(x);
x.setParent(sNode);
makeInsertedTreeBalance(x);
count++;
}
public void delete(int val) throws Exception {
if (root == null)
return ;
RBTreeNode x = search(val, MatchType.E);
if (x == null) //未找到删除节点
return ;
count--;
//如果待删除节点为根节点,则直接删除
if (count == 0) {
root = null;
return;
}
//以二叉树的节点删除方式,进行节点删除
RBTreeNode lc = x.getLeftChild(); //right child
RBTreeNode rc = x.getRightChild(); //left child
RBTreeNode rn = null; //被替换的节点replace node
if (lc != null && rc != null) {
//需要进行节点替换
RBTreeNode lrm = getRigthMostNode(lc);
RBTreeNode rlm = getLeftMostNode(rc);
switch (0) {
case 0:
// if (lrm.isLeaf() && lrm.getColor() == Color.Red){
// rn = lrm;
// break;
// }
// if (rlm.isLeaf() && lrm.getColor() == Color.Red) {
// rn = rlm;
// break;
// }
if (!lrm.isLeaf())
rn = lrm;
else
rn = rlm;
}
}
if (rn != null) {
int temp = x.getValue(); //为调试时观察方便
x.setValue(rn.getValue());
rn.setValue(temp);
x = rn;
}
if (x.getLeftChild() != null && x.getRightChild() != null)
throw new Exception("获取删除节点错误");
//x为待删除的节点
//简单情况1,待删除的节点为红色
RBTreeNode p = x.getParent();
if (x.getColor() == Color.Red) {
RBTreeNode nstr = null; //新子树的根节点。new sub tree root
if (x.getLeftChild() != null) {
nstr = x.getLeftChild();
}
else if (x.getRightChild() != null) {
nstr = x.getRightChild();
}
if (nstr != null)
nstr.setParent(p);
if (p == null) {
throw new Exception("红节点的父节点不可能为空");
}
if (p.getLeftChild() == x) {
p.setLeftChild(nstr);
}
else {
p.setRightChild(nstr);
}
return ;
}
//简单情况2,待删除节点子节点为黑色,其子节点为红色
if (x.getColor() == Color.Black) {
lc = x.getLeftChild();
rc = x.getRightChild();
if (lc != null && lc.getColor() == Color.Red) {
lc.setColor(Color.Black);
if (p == null) {
root = lc;
return;
}
if (p.getLeftChild() == x) {
p.setLeftChild(lc);
}
else {
p.setRightChild(lc);
}
lc.setParent(p);
return ;
}
if (rc != null && rc.getColor() == Color.Red) {
rc.setColor(Color.Black);
if (p == null) {
root = rc;
return;
}
if (p.getLeftChild() == x) {
p.setLeftChild(rc);
}
else {
p.setRightChild(rc);
}
rc.setParent(p);
return ;
}
}
//删除x节点,并进行重新平衡
RBTreeNode nstr = null; //new sub tree root
if (x.getLeftChild() != null)
nstr = x.getLeftChild();
else if (x.getRightChild() != null)
nstr = x.getRightChild();
p = x.getParent();
if (p == null) {
throw new Exception("此处为处理至多只有一个非空子树的删除情况,x为根节点而且有一个节点为黑色节点,这种情况不可能出现");
}
if (p.getLeftChild() == x)
p.setLeftChild(nstr);
else
p.setRightChild(nstr);
if (nstr != null)
nstr.setParent(p);
//重新平衡n和p
makeDeletedTreeBalance(nstr, p);
}
public RBTreeNode[] getAscOrderArray() {
if (root == null)
return null;
RBTreeNode[] ary = new RBTreeNode[count];
int pos = fillArrayInOrd(ary, 0, root);
if (pos != count)
return null;
return ary;
}
public void printInAscOrd() {
RBTreeNode[] ary = getAscOrderArray();
if (ary == null) {
System.out.println("空树");
return;
}
for (int i = 0; i < ary.length; i++)
System.out.print("[" + ary[i].getValue() + "]");
System.out.println();
}
//辅助函数//
private int fillArrayInOrd(RBTreeNode[] ary, int pos, RBTreeNode n) {
int npos = pos;
if (n.getLeftChild() != null)
npos = fillArrayInOrd(ary, pos, n.getLeftChild());
ary[npos] = n;
npos++;
if (n.getRightChild() != null)
npos = fillArrayInOrd(ary, npos, n.getRightChild());
return npos;
}
private RBTreeNode getSibling(RBTreeNode n) {
RBTreeNode p = n.getParent();
if (p != null) {
if (n == p.getLeftChild())
return p.getRightChild();
return p.getLeftChild();
}
return null;
}
private RBTreeNode rotateLeft(RBTreeNode n) {
RBTreeNode rc = n.getRightChild();
RBTreeNode subTree3 = rc.getLeftChild();
RBTreeNode p = n.getParent();
n.setRightChild(subTree3);
if (subTree3 != null) {
subTree3.setParent(n);
}
rc.setLeftChild(n);
n.setParent(rc);
rc.setParent(p);
if (p == null) {
root = rc;
return rc;
}
if (p.getLeftChild() == n) {
p.setLeftChild(rc);
}
else {
p.setRightChild(rc);
}
return rc;
}
private RBTreeNode rotateRight(RBTreeNode n) {
RBTreeNode lc = n.getLeftChild();
RBTreeNode subTree2 = lc.getRightChild();
RBTreeNode p = n.getParent();
n.setLeftChild(subTree2);
if (subTree2 != null)
subTree2.setParent(n);
lc.setRightChild(n);
n.setParent(lc);
lc.setParent(p);
if (p == null){
root = lc;
return lc;
}
if (p.getLeftChild() == n) {
p.setLeftChild(lc);
}
else {
p.setRightChild(lc);
}
return lc;
}
//搜索函数//
private RBTreeNode search(int val) {
if (root == null)
return null;
return search(root, val);
}
private RBTreeNode search(RBTreeNode n, int val) {
if (n.getValue() == val)
return n;
if (n.getValue() > val) {
if (n.getLeftChild() != null)
return search(n.getLeftChild(), val);
}
else {
if (n.getRightChild() != null)
return search(n.getRightChild(), val);
}
return n;
}
private RBTreeNode getLittleBigger(RBTreeNode n) {
if (n.getRightChild() != null)
return getLeftMostNode(n.getRightChild());
RBTreeNode p = n.getParent();
RBTreeNode s = n;
while (p != null) {
if (p.getLeftChild() == s)
break;
s = p;
p = p.getParent();
}
return p;
}
private RBTreeNode getLittleSmaller(RBTreeNode n) {
if (n.getLeftChild() != null)
return getRigthMostNode(n.getLeftChild());
RBTreeNode p = n.getParent();
RBTreeNode s = n;
while (p != null) {
if (p.getRightChild() == s)
break;
s = p;
p = p.getParent();
}
return p;
}
private RBTreeNode getLeftMostNode(RBTreeNode n) {
RBTreeNode l = n;
while (l.getLeftChild() != null) {
l = l.getLeftChild();
}
return l;
}
private RBTreeNode getRigthMostNode(RBTreeNode n) {
RBTreeNode r = n;
while (r.getRightChild() != null) {
r = r.getRightChild();
}
return r;
}
//插入操作//
private void makeInsertedTreeBalance(RBTreeNode x) throws Exception {
while (keepBalancing(x)) {
RBTreeNode p = x.getParent();
RBTreeNode pp = p.getParent();
BalanceCategory category = getBalanceCategory(x, p, pp);
switch (category) {
case CategoryA:
x = processCategoryA(x, p, pp);
break;
case CategoryB:
x = processCategoryB(x, p, pp);
break;
default:
throw new Exception("Unkonw category.fatal error");
}
}
if (x.isRoot())
root = x;
root.setColor(Color.Black);
}
private boolean keepBalancing(RBTreeNode x) {
if (x.isRoot() != true && x.getColor() == Color.Red) {
if (x.getParent().isRoot() == true)
return false;
if (x.getParent().getColor() == Color.Black)
return false;
return true;
}
return false;
}
private enum BalanceCategory {CategoryA, CategoryB};
private BalanceCategory getBalanceCategory(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
if (pp.getLeftChild() == p)
return BalanceCategory.CategoryA;
return BalanceCategory.CategoryB;
}
private RBTreeNode processCategoryA(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
BalanceCase balanceCase = getCategoryABalanceCase(x, p, pp);
if (balanceCase == BalanceCase.Case1) {
//处理父节点的兄弟节点为红节点的情况
return processCategoryACase1(x, p, pp);
}
else {
if (balanceCase == BalanceCase.Case2) {
//处理当前节点为右子节点的情况
return processCategoryACase2(x, p, pp);
}
//case2处理后得到的结果就是case3,此处进行case3的处理
return processCategoryACase3(x, p, pp);
}
}
private RBTreeNode processCategoryB(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
BalanceCase balanceCase = getCategoryBBalanceCase(x, p, pp);
if (balanceCase == BalanceCase.Case1) {
//处理父节点的兄弟节点为红节点的情况
return processCategoryBCase1(x, p, pp);
}
else {
if (balanceCase == BalanceCase.Case2) {
//处理当前节点为右子节点的情况
return processCategoryBCase2(x, p, pp);
}
//case2处理后得到的结果就是case3,此处进行case3的处理
return processCategoryBCase3(x, p, pp);
}
}
private enum BalanceCase { Case1, Case2, Case3 };
private BalanceCase getCategoryABalanceCase(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode ancle = pp.getRightChild();
if (ancle != null && ancle.getColor() == Color.Red)
return BalanceCase.Case1;
else if (p.getRightChild() == x)
return BalanceCase.Case2;
return BalanceCase.Case3;
}
private BalanceCase getCategoryBBalanceCase(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode ancle = pp.getLeftChild();
if (ancle != null && pp.getLeftChild().getColor() == Color.Red)
return BalanceCase.Case1;
else if (p.getLeftChild() == x)
return BalanceCase.Case2;
return BalanceCase.Case3;
}
private RBTreeNode processCategoryACase1(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode ancle = pp.getRightChild();
pp.setColor(Color.Red);
p.setColor(Color.Black);
ancle.setColor(Color.Black);
return pp;
}
private RBTreeNode processCategoryACase2(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode temp = x.getLeftChild();
p.setRightChild(temp);
if (temp != null)
temp.setParent(p);
x.setLeftChild(p);
p.setParent(x);
pp.setLeftChild(x);
x.setParent(pp);
return p;
}
private RBTreeNode processCategoryACase3(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode temp = p.getRightChild();
RBTreeNode ppp = pp.getParent();
boolean isRight = false;
if (ppp != null) {
if (ppp.getRightChild() == pp)
isRight = true;
}
pp.setLeftChild(temp);
if (temp != null)
temp.setParent(pp);
pp.setColor(Color.Red);
p.setRightChild(pp);
p.setParent(pp.getParent());
pp.setParent(p);
p.setColor(Color.Black);
if (ppp != null){
if (isRight)
ppp.setRightChild(p);
else
ppp.setLeftChild(p);
}
return p;
}
private RBTreeNode processCategoryBCase1(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode ancle = pp.getLeftChild();
pp.setColor(Color.Red);
p.setColor(Color.Black);
ancle.setColor(Color.Black);
return pp;
}
private RBTreeNode processCategoryBCase2(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode temp = x.getRightChild();
p.setLeftChild(temp);
if (temp != null)
temp.setParent(p);
x.setRightChild(p);
p.setParent(x);
pp.setRightChild(x);
x.setParent(pp);
return p;
}
private RBTreeNode processCategoryBCase3(RBTreeNode x, RBTreeNode p, RBTreeNode pp) {
RBTreeNode temp = p.getLeftChild();
RBTreeNode ppp = pp.getParent();
boolean isRight = false;
if (ppp != null) {
if (ppp.getRightChild() == pp)
isRight = true;
}
pp.setRightChild(p.getLeftChild());
if (temp != null)
temp.setParent(pp);
pp.setColor(Color.Red);
p.setLeftChild(pp);
p.setParent(pp.getParent());
pp.setParent(p);
p.setColor(Color.Black);
if (ppp != null){
if (isRight)
ppp.setRightChild(p);
else
ppp.setLeftChild(p);
}
return p;
}
/删除函数/
//由维基的红黑树删除算法中描述的6种情况
private enum DeleteBalanceCase {case1, case2l, case2r, case3, case4, case5l, case5r, case6l, case6r};
private DeleteBalanceCase getDeleteCase(RBTreeNode n, RBTreeNode p, RBTreeNode s) throws Exception {
if (p == null) //平衡至根节点
return DeleteBalanceCase.case1;
if (s == null)
throw new Exception("树结构出现错误");
if (s.getColor() == Color.Red) {
if (n == p.getLeftChild())
return DeleteBalanceCase.case2l;
return DeleteBalanceCase.case2r;
}
else {
boolean slcIsBlack = false;
boolean srcIsBlack = false;
if (s.getLeftChild() == null || s.getLeftChild().getColor() == Color.Black)
slcIsBlack = true;
if (s.getRightChild() == null || s.getRightChild().getColor() == Color.Black)
srcIsBlack = true;
if (slcIsBlack == true && srcIsBlack == true) {
if (p.getColor() == Color.Black) {
return DeleteBalanceCase.case3;
}
else {
return DeleteBalanceCase.case4;
}
}
if (n == p.getLeftChild()) {
if (srcIsBlack) //slcIsBlack must be false
return DeleteBalanceCase.case5l;
return DeleteBalanceCase.case6l;
}
else {
if (slcIsBlack) //srcIsBlack must be false
return DeleteBalanceCase.case5r;
return DeleteBalanceCase.case6r;
}
}
}
private void makeDeletedTreeBalance(RBTreeNode n, RBTreeNode p) throws Exception {
RBTreeNode s = null; //sibling
if (p.getLeftChild() == n)
s = p.getRightChild();
else
s = p.getLeftChild();
while (true) {
DeleteBalanceCase c = getDeleteCase(n, p, s);
switch (c) {
case case1:
//达到根节点
return;
case case2l:
//左旋,在原有节点继续平衡
p.setColor(Color.Red);
s.setColor(Color.Black);
rotateLeft(p);
s = p.getRightChild();
break;
case case2r:
//右旋,在原节点继续平衡
p.setColor(Color.Red);
s.setColor(Color.Black);
rotateRight(p);
s = p.getLeftChild();
break;
case case3:
s.setColor(Color.Red);
n = p;
p = n.getParent();
s = getSibling(n);
break;
case case4:
p.setColor(Color.Black);
s.setColor(Color.Red);
return;
case case5l:
s.setColor(Color.Red);
s.getLeftChild().setColor(Color.Black);
s = rotateRight(s);
break;
case case5r:
s.setColor(Color.Red);
s.getRightChild().setColor(Color.Black);
s = rotateLeft(s);
break;
case case6l:
s.setColor(p.getColor());
p.setColor(Color.Black);
s.getRightChild().setColor(Color.Black);
rotateLeft(p);
return;
case case6r:
s.setColor(p.getColor());
p.setColor(Color.Black);
s.getLeftChild().setColor(Color.Black);
rotateRight(p);
return;
}
//
}
}
/测试用例/
private static int[] tree1Ary = {53, 12, 27, 99, 46, 5, 38};
private static RBTree buildTree1() {
RBTree tree = new RBTree();
try {
for (int i = 0; i < tree1Ary.length; i++) {
tree.insert(tree1Ary[i]);
}
return tree;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void testInsertCase1() {
RBTree tree = buildTree1();
if (tree == null)
System.out.println("构造树出现错误");
tree.printInAscOrd();
}
private static int[] tree2Ary = {524, 3, 12, 198, 137, 652, 911, 1, 0, 999};
private static RBTree buildTree2() {
RBTree tree = new RBTree();
try {
for (int i = 0; i < tree2Ary.length; i++) {
tree.insert(tree2Ary[i]);
}
return tree;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void testInsertCase2() {
RBTree tree = buildTree2();
if (tree == null)
System.out.println("构造树出现错误");
tree.printInAscOrd();
}
private static int[] tree3Ary = {111, 222, 333, 444, 555, 666, 777, 888, 999, 456};
public static RBTree buildTree3() {
RBTree tree = new RBTree();
try {
for (int i = 0; i < tree3Ary.length; i++) {
tree.insert(tree3Ary[i]);
}
return tree;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void testInsertCase3() {
RBTree tree = buildTree3();
if (tree == null)
System.out.println("构造树出现错误");
tree.printInAscOrd();
}
private static int[] tree4Ary = {471, 192, 4, 798, 3, 1, 500, 250, 521, 650, 999, 72, 108, 25, 14};
public static RBTree buildTree4() {
RBTree tree = new RBTree();
try {
for (int i = 0; i < tree4Ary.length; i++) {
tree.insert(tree4Ary[i]);
}
return tree;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void testInsertCase4() {
RBTree tree = buildTree4();
if (tree == null)
System.out.println("构造树出现错误");
tree.printInAscOrd();
}
private static int[] tree5Ary = {64, 88, 100, 67, 788, 675, 234, 1, 444, 209, 578, 23, 777, 345, 904, 755, 289, 666, 498, 629, 103, 402, 388, 922, 518, 101, 823, 65};
public static RBTree buildTree5() {
RBTree tree = new RBTree();
try {
for (int i = 0; i < tree5Ary.length; i++) {
tree.insert(tree5Ary[i]);
}
return tree;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void testInsertCase5() {
RBTree tree = buildTree5();
if (tree == null)
System.out.println("构造树出现错误");
tree.printInAscOrd();
}
public static void testDeleteCase1() {
RBTree tree = new RBTree();
try {
tree.insert(50);
tree.insert(15);
tree.insert(100);
tree.printInAscOrd();
tree.delete(15);
tree.printInAscOrd();
tree.delete(100);
tree.printInAscOrd();
tree.delete(50);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void testDeleteCase2() {
RBTree tree = buildTree1();
if (tree == null) {
System.out.println("构造树错误");
return;
}
tree.printInAscOrd();
for (int i = 0; i < tree1Ary.length; i++) {
try {
System.out.println("删除"+tree1Ary[i]);
tree.delete(tree1Ary[i]);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void testDeleteCate2() {
RBTree tree = buildTree2();
if (tree == null) {
System.out.println("构造树错误");
return;
}
tree.printInAscOrd();
for (int i = 0; i < tree2Ary.length; i++) {
try {
System.out.println("删除"+tree2Ary[i]);
tree.delete(tree2Ary[i]);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void testDeleteCate3() {
RBTree tree = buildTree3();
if (tree == null) {
System.out.println("构造树错误");
return;
}
tree.printInAscOrd();
for (int i = 0; i < tree3Ary.length; i++) {
try {
System.out.println("删除"+tree3Ary[i]);
tree.delete(tree3Ary[i]);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void testDeleteCate4() {
RBTree tree = buildTree4();
if (tree == null) {
System.out.println("构造树错误");
return;
}
tree.printInAscOrd();
for (int i = 0; i < tree4Ary.length; i++) {
try {
System.out.println("删除"+tree4Ary[i]);
tree.delete(tree4Ary[i]);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void testDeleteCate5() {
RBTree tree = buildTree4();
if (tree == null) {
System.out.println("构造树错误");
return;
}
tree.printInAscOrd();
for (int i = 0; i < tree4Ary.length; i++) {
try {
System.out.println("删除"+tree4Ary[i]);
tree.delete(tree4Ary[i]);
tree.printInAscOrd();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}