Java数据结构--红黑树

红黑树黑高度的验证方法

  public void depthFirst(){
        depthFirst(root,0);//包装方法
    }
    private void depthFirst(BinaryNode node,int count){//count用于保存黑高度
        if (node==null) {
            System.out.println(count);return;}//如果到达了空节点打印出黑高度
        else {
            if(node.color==BLACK){
                depthFirst(node.leftChild,count+1);//如果节点是黑色 黑高度计数器增加
                depthFirst(node.rightChild,count+1);//如果节点是黑色 黑高度计数器增加
            }
            else {
                depthFirst(node.leftChild,count); //不是黑色 步增加计数
                depthFirst(node.rightChild,count);
            }
        }

    }

test类进行随机添加、删除检验

如果打印出的黑高度相同 证明RedBlackTree类保持了红黑树的性质

/**
 * Created by root on 16-3-16.
 */
import java.util.Random;

public class Test {
    public static void main(String[] args){
        RedBlackTree tree =new RedBlackTree();
        Random random=new Random();
        //随机法检验
        int k=200;
        Integer [] a=new Integer[k];
        for(int i=0;i<k;i++){
            a[i]=random.nextInt(100)+1;
        }

        for(Integer x :a){
            tree.insert(x);
        }
        for(int i=0;i<150;i++){
        tree.remove(random.nextInt(100)+1);}

        tree.depthFirst();
    }
}

BinaryNode类



/**
 * Created by root on 16-3-16.
 */
public class BinaryNode<E extends Comparable> {
    public static boolean RED =true;  //用布尔型变量存放颜色值
    public static boolean BLACK= false;
    BinaryNode parent;
    BinaryNode leftChild;
    BinaryNode rightChild;
    E item;
    boolean color;
    public BinaryNode(E item){ //默认红色 parent leftChild rightChild 默认都是null
        this(item,RED);
    }
    public BinaryNode(E item,boolean color){
        this(item,color,null,null,null);
    }
    public BinaryNode(E item,boolean color,BinaryNode parent,BinaryNode leftChild,BinaryNode rightChild){ //构造器
        this.item=item;
        this.color=color;
        this.parent=parent;
        this.leftChild=leftChild;
        this.rightChild=rightChild;
    }
}

RedBlackTree类中避免空指针的方法

 public static boolean BLACK = false;
    public static boolean RED = true;
    BinaryNode root;
    private void setParent(BinaryNode child,BinaryNode parent){ //setParent方法 避免空指针异常
        if(child!=null){
            child.parent=parent;
        }
    }
    private boolean setColor(BinaryNode node, boolean color) { //设置颜色 避免空指针异常
        if (node != null) {
            node.color = color;
            return true;
        }
        return false;
    }

    private void setLeftChild(BinaryNode child, BinaryNode parent) {//为parent设置左子树 避免空指针异常
        if (parent != null) {
            parent.leftChild = child;
        }
        if (child != null) {
            child.parent = parent;
        }
    }

    private void setRightChild(BinaryNode child, BinaryNode parent) {//同上
        if (parent != null) {
            parent.rightChild = child;
        }
        if (child != null) {
            child.parent = parent;
        }
    }

    private boolean isBLACKOrNull(BinaryNode node) {//判断节点是空节点或者是黑色节点
        return node == null || node.color == BLACK;
    }

    private boolean isRoot(BinaryNode node) { //节点是root节点?
        return node != null && node.parent == null;
    }

    private boolean isLeftChildOf(BinaryNode child, BinaryNode parent) {//是否是右child
        return parent != null && parent.leftChild == child;
    }

    private boolean isRightChildOf(BinaryNode child, BinaryNode parent) {//是否是左child
        return parent != null && parent.rightChild == child;
    }

    private boolean hasTwoChildren(BinaryNode node) {//是否有两个child
        return node != null && node.leftChild != null && node.rightChild != null;
    }

    private boolean hasOnlyLeftChild(BinaryNode node) {//只有左child
        return node != null && node.leftChild != null && node.rightChild == null;
    }

    private boolean hasOnlyRightChild(BinaryNode node) {//只有右child
        return node != null && node.leftChild == null && node.rightChild != null;
    }

    private boolean isLeaf(BinaryNode node) {//是否是树叶?
        return node != null && node.leftChild == null && node.rightChild == null;
    }

左旋

 private void leftRotate(BinaryNode x) {
        BinaryNode y = x.rightChild;
        setRightChild(y.leftChild, x);

        if (isRoot(x)) {
            this.root = y;
            y.parent = x.parent;
        } else {
            if (isLeftChildOf(x, x.parent)) {
                setLeftChild(y, x.parent);
            } else {
                setRightChild(y, x.parent);
            }
        }
        setLeftChild(x, y);
    }

右旋

 private void rightRotate(BinaryNode y) {
        BinaryNode x = y.leftChild;
        setLeftChild(x.rightChild, y);
        if (isRoot(y)) {
            this.root = x;
            x.parent = y.parent;
        } else {
            if (isLeftChildOf(y, y.parent)) {
                setLeftChild(x, y.parent);
            } else {
                setRightChild(x, y.parent);
            }
        }
        setRightChild(y, x);
    }

增加节点后的修复:新节点是红色的

如果新节点的parent是黑色的 不需要修复

  BinaryNode uncle = grandparent.rightChild;
                if (uncle != null && uncle.color == RED) {
                    setColor(uncle, BLACK);
                    setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    node = grandparent;
                    continue;

 leftRotate(parent);
                    BinaryNode tmp = node;
                    node = parent;
                    parent = node;

  setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    rightRotate(grandparent);

删除的操作

private void remove(BinaryNode node) {
        boolean removeColor;
        BinaryNode x;
        BinaryNode pOfx;
        if (hasTwoChildren(node)) {
         BinaryNode inOrderSuccessor =node.rightChild;
            while (inOrderSuccessor.leftChild!=null){
                inOrderSuccessor=inOrderSuccessor.leftChild;
            }
            removeColor=inOrderSuccessor.color;
            x=inOrderSuccessor.rightChild;
            if(isRightChildOf(inOrderSuccessor,node)){
                setLeftChild(node.leftChild,inOrderSuccessor);
                pOfx=inOrderSuccessor;
            }
            else {
                pOfx=inOrderSuccessor.parent;
                setLeftChild(inOrderSuccessor.rightChild,inOrderSuccessor.parent);
                setLeftChild(node.leftChild,inOrderSuccessor);
                setRightChild(node.rightChild,inOrderSuccessor);
            }
            if(isRoot(node)){
                this.root=inOrderSuccessor;
                inOrderSuccessor.parent=node.parent;
            }
            else {
                if(isLeftChildOf(node,node.parent)){
                    setLeftChild(inOrderSuccessor,node.parent);
                }
                else {
                    setRightChild(inOrderSuccessor,node.parent);
                }
            }
            setColor(inOrderSuccessor,node.color);
            if(removeColor==BLACK){
                removeFix(x,pOfx);
            }
        } else {
            BinaryNode child;
            if (hasOnlyLeftChild(node)) {
                child = node.leftChild;
            } else if (hasOnlyRightChild(node)) {
                child = node.rightChild;
            } else {
                child = null;
            }
            x = child;
            removeColor = node.color;
            pOfx = node.parent;
            if (isLeftChildOf(node, node.parent)) {
                setLeftChild(child, node.parent);
            } else if (isRoot(node)) {
                this.root = child;
                setParent(child,node.parent);
            } else {
                setRightChild(child, node.parent);
            }
            if (removeColor == BLACK) {
                removeFix(x, pOfx);
            }

        }
        this.root.color=BLACK;

    }

删除后的修复

如果被删除的节点有两个children x就是在执行删除之前 node的中序后继的右子树 pOfx是执行删除操作之后x的parent

如果被删除的节点只有一个child或者没有child 那么 x就是node的唯一child或者 是null pOfx是node的parent

最后给出RedBlackTree类



/**
 * Created by root on 16-3-16.
 */
public class RedBlackTree<E extends Comparable> {
    public static boolean BLACK = false;
    public static boolean RED = true;
    BinaryNode root;
    private void setParent(BinaryNode child,BinaryNode parent){
        if(child!=null){
            child.parent=parent;
        }
    }
    private boolean setColor(BinaryNode node, boolean color) {
        if (node != null) {
            node.color = color;
            return true;
        }
        return false;
    }

    private void setLeftChild(BinaryNode child, BinaryNode parent) {
        if (parent != null) {
            parent.leftChild = child;
        }
        if (child != null) {
            child.parent = parent;
        }
    }

    private void setRightChild(BinaryNode child, BinaryNode parent) {
        if (parent != null) {
            parent.rightChild = child;
        }
        if (child != null) {
            child.parent = parent;
        }
    }

    private boolean isBLACKOrNull(BinaryNode node) {
        return node == null || node.color == BLACK;
    }

    private boolean isRoot(BinaryNode node) {
        return node != null && node.parent == null;
    }

    private boolean isLeftChildOf(BinaryNode child, BinaryNode parent) {
        return parent != null && parent.leftChild == child;
    }

    private boolean isRightChildOf(BinaryNode child, BinaryNode parent) {
        return parent != null && parent.rightChild == child;
    }

    private boolean hasTwoChildren(BinaryNode node) {
        return node != null && node.leftChild != null && node.rightChild != null;
    }

    private boolean hasOnlyLeftChild(BinaryNode node) {
        return node != null && node.leftChild != null && node.rightChild == null;
    }

    private boolean hasOnlyRightChild(BinaryNode node) {
        return node != null && node.leftChild == null && node.rightChild != null;
    }

    private boolean isLeaf(BinaryNode node) {
        return node != null && node.leftChild == null && node.rightChild == null;
    }

    private void leftRotate(BinaryNode x) {
        BinaryNode y = x.rightChild;
        setRightChild(y.leftChild, x);

        if (isRoot(x)) {
            this.root = y;
            y.parent = x.parent;
        } else {
            if (isLeftChildOf(x, x.parent)) {
                setLeftChild(y, x.parent);
            } else {
                setRightChild(y, x.parent);
            }
        }
        setLeftChild(x, y);
    }

    private void rightRotate(BinaryNode y) {
        BinaryNode x = y.leftChild;
        setLeftChild(x.rightChild, y);
        if (isRoot(y)) {
            this.root = x;
            x.parent = y.parent;
        } else {
            if (isLeftChildOf(y, y.parent)) {
                setLeftChild(x, y.parent);
            } else {
                setRightChild(x, y.parent);
            }
        }
        setRightChild(y, x);
    }


    private void insertFix(BinaryNode node) {
        BinaryNode parent;
        while ((parent = node.parent) != null && parent.color == RED) {
            BinaryNode grandparent = parent.parent;
            if (isLeftChildOf(parent, grandparent)) {
                BinaryNode uncle = grandparent.rightChild;
                if (uncle != null && uncle.color == RED) {
                    setColor(uncle, BLACK);
                    setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    node = grandparent;
                    continue;
                } else if (isRightChildOf(node, parent)) {
                    leftRotate(parent);
                    BinaryNode tmp = node;
                    node = parent;
                    parent = node;
                } else {
                    setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    rightRotate(grandparent);
                }
            } else {
                BinaryNode uncle = grandparent.leftChild;
                if (uncle != null && uncle.color == RED) {
                    setColor(uncle, BLACK);
                    setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    node = grandparent;
                    continue;
                } else if (isLeftChildOf(node, parent)) {
                    rightRotate(parent);
                    BinaryNode tmp = node;
                    node = parent;
                    parent = tmp;
                } else {
                    setColor(parent, BLACK);
                    setColor(grandparent, RED);
                    leftRotate(grandparent);
                }
            }
        }
        setColor(root, BLACK);
    }

    public void insert(E item) {
        BinaryNode newNode = new BinaryNode(item);
        if (this.root == null) {
            this.root = newNode;
            setColor(root, BLACK);
            return;
        }
        BinaryNode prev = root;
        BinaryNode next = root;
        while (next != null) {
            prev = next;
            int comparison = item.compareTo(prev.item);
            if (comparison == 0) {
                return;
            } else if (comparison < 0) {
                next = prev.leftChild;
            } else {
                next = prev.rightChild;
            }
        }
        int comparison = item.compareTo(prev.item);
        if (comparison < 0) {
            setLeftChild(newNode, prev);
        } else {
            setRightChild(newNode, prev);
        }
        insertFix(newNode);
    }


    public void remove(E item){
        BinaryNode node=root;
        while(node!=null){
            int comparison=item.compareTo(node.item);
            if(comparison==0){
                remove(node);
                return;
            }
            else if(comparison<0){
                node=node.leftChild;
            }
            else {
                node=node.rightChild;
            }
        }
    }
    private void remove(BinaryNode node) {
        boolean removeColor;
        BinaryNode x;
        BinaryNode pOfx;
        if (hasTwoChildren(node)) {
         BinaryNode inOrderSuccessor =node.rightChild;
            while (inOrderSuccessor.leftChild!=null){
                inOrderSuccessor=inOrderSuccessor.leftChild;
            }
            removeColor=inOrderSuccessor.color;
            x=inOrderSuccessor.rightChild;
            if(isRightChildOf(inOrderSuccessor,node)){
                setLeftChild(node.leftChild,inOrderSuccessor);
                pOfx=inOrderSuccessor;
            }
            else {
                pOfx=inOrderSuccessor.parent;
                setLeftChild(inOrderSuccessor.rightChild,inOrderSuccessor.parent);
                setLeftChild(node.leftChild,inOrderSuccessor);
                setRightChild(node.rightChild,inOrderSuccessor);
            }
            if(isRoot(node)){
                this.root=inOrderSuccessor;
                inOrderSuccessor.parent=node.parent;
            }
            else {
                if(isLeftChildOf(node,node.parent)){
                    setLeftChild(inOrderSuccessor,node.parent);
                }
                else {
                    setRightChild(inOrderSuccessor,node.parent);
                }
            }
            setColor(inOrderSuccessor,node.color);
            if(removeColor==BLACK){
                removeFix(x,pOfx);
            }
        } else {
            BinaryNode child;
            if (hasOnlyLeftChild(node)) {
                child = node.leftChild;
            } else if (hasOnlyRightChild(node)) {
                child = node.rightChild;
            } else {
                child = null;
            }
            x = child;
            removeColor = node.color;
            pOfx = node.parent;
            if (isLeftChildOf(node, node.parent)) {
                setLeftChild(child, node.parent);
            } else if (isRoot(node)) {
                this.root = child;
                setParent(child,node.parent);
            } else {
                setRightChild(child, node.parent);
            }
            if (removeColor == BLACK) {
                removeFix(x, pOfx);
            }

        }
        this.root.color=BLACK;

    }

    private void removeFix(BinaryNode x, BinaryNode pOfx) {
        while (isBLACKOrNull(x) && pOfx != null) {
            if (isLeftChildOf(x, pOfx)) {
                BinaryNode w = pOfx.rightChild;
                if (w != null && w.color == RED) {
                    setColor(w, BLACK);
                    setColor(pOfx, RED);
                    leftRotate(pOfx);
                    w = pOfx.rightChild;
                } else if (isBLACKOrNull(w.leftChild) && isBLACKOrNull(w.rightChild)) {
                    setColor(w, RED);
                    x = pOfx;
                    pOfx = x.parent;
                } else {
                    if (w.rightChild!=null && w.rightChild.color==RED) {
                        setColor(w,w.parent.color);
                        setColor(w.parent,BLACK);
                        setColor(w.rightChild,BLACK);
                        leftRotate(pOfx);
                        x=this.root;  //退出循环 并且把root设置为黑色
                        break;
                    } else { //w.leftChild.color== RED && w.rightChild.color != RED
                        setColor(w.leftChild,BLACK);
                        setColor(w,RED);
                        rightRotate(w);
                        w=pOfx.rightChild;
                    }
                }
            } else {
                BinaryNode w = pOfx.leftChild;
                if (w != null && w.color == RED) {
                    setColor(w, BLACK);
                    setColor(pOfx, RED);
                    rightRotate(pOfx);
                    w = pOfx.leftChild;
                } else if (isBLACKOrNull(w.leftChild) && isBLACKOrNull(w.rightChild)) {
                    setColor(w, RED);
                    x = pOfx;
                    pOfx = x.parent;
                }
                else {
                    if(w.leftChild!=null && w.leftChild.color==RED){
                        setColor(w,pOfx.color);
                        setColor(pOfx,BLACK);
                        setColor(w.leftChild,BLACK);
                        rightRotate(pOfx);
                        x=this.root;
                        break;
                    }
                    else {
                        setColor(w.rightChild,BLACK);
                        setColor(w,RED);
                        leftRotate(w);
                        w=pOfx.leftChild;
                    }
                }
            }
        }
        setColor(x,BLACK);
    }

    public static class Queue {
        linkedNode beginMaker;
        linkedNode endMaker;

        public boolean isEmpty() {
            return size == 0;
        }

        private int size;

        public Queue() {
            beginMaker = new linkedNode(null, null, null);
            endMaker = new linkedNode(null, beginMaker, null);
            beginMaker.next = endMaker;
            this.size = 0;
        }

        public void add(BinaryNode el) {
            linkedNode prevOfEndMaker = endMaker.prev;
            linkedNode newNode = new linkedNode(el, prevOfEndMaker, endMaker);
            prevOfEndMaker.next = newNode;
            endMaker.prev = newNode;
            this.size++;
        }

        public BinaryNode remove() {
            if (size != 0) {
                linkedNode top = beginMaker.next;
                BinaryNode el = top.el;
                linkedNode nextOfTop = top.next;
                beginMaker.next = nextOfTop;
                nextOfTop.prev = beginMaker;
                size--;
                return el;
            }
            return null;
        }

    }

    public static class linkedNode {
        linkedNode prev;
        linkedNode next;
        BinaryNode el;

        public linkedNode(BinaryNode el) {
            this(el, null, null);
        }

        public linkedNode() {
            this(null, null, null);
        }

        public linkedNode(BinaryNode el, linkedNode prev, linkedNode next) {
            this.el = el;
            this.prev = prev;
            this.next = next;
        }
    }


    public void breadthFirstPrint() {
        Queue q = new Queue();
        BinaryNode node = root;
        q.add(node);
        while (!q.isEmpty()) {
            node = q.remove();
            System.out.println(node.item.toString()+node.color);
            if (node.leftChild != null) {
                q.add(node.leftChild);
            }
            if (node.rightChild != null) {
                q.add(node.rightChild);
            }
        }

    }


    public void inOrderPrint() {
        inOrderPrint(this.root);
    }

    public void inOrderPrint(BinaryNode node) {
        if (node == null) return;
        inOrderPrint(node.leftChild);
        System.out.println(node.item);
        inOrderPrint(node.rightChild);

    }
    public void depthFirst(){
        depthFirst(root,0);
    }
    private void depthFirst(BinaryNode node,int count){
        if (node==null) {
            System.out.println(count);return;}
        else {
            if(node.color==BLACK){
                depthFirst(node.leftChild,count+1);
                depthFirst(node.rightChild,count+1);
            }
            else {
                depthFirst(node.leftChild,count);
                depthFirst(node.rightChild,count);
            }
        }

    }
}
posted @ 2016-03-14 23:41  Salaku  阅读(289)  评论(0编辑  收藏  举报