红黑树的java实现
经过几个星期的努力,红黑树终于弄清楚了。
先附上代码,然后贴上自己的分析图
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(); } } } }