红黑棋Java_红黑树的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();

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值