java红黑树的例子

红黑树是一种经典的数据结构,在linux内存管理、nginx 等很多地方用到它。主要操作包括插入、删除,其中插入6种情况,删除8种情况,详细的思路就不说了,如果不太明白的请参考算法导论13章,看的时候一定要 把每一种插入、删除的情况在纸上自己画出来,这样会节省你很多时间。

  • Node类
public class Node {
    private Node left;
    private Node right;
    private Node parent;
    private Color color;
    private int value;
    public Node(Node left, Node right, Node parent, Color color, int value) {
        super();
        this.left = left;
        this.right = right;
        this.parent = parent;
        this.color = color;
        this.value = value;
    }
    public Node() {
    }
    public Node(int value) {
        this(null, null, null, null, value);
    }
    public Node getLeft() {
        return left;
    }
    public void setLeft(Node left) {
        this.left = left;
    }
    public Node getRight() {
        return right;
    }
    public void setRight(Node right) {
        this.right = right;
    }
    public Node getParent() {
        return parent;
    }
    public void setParent(Node parent) {
        this.parent = parent;
    }
    public Color getColor() {
        return color;
    }
    public void setColor(Color color) {
        this.color = color;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
}
  • Color枚举
public enum Color {
    RED, BLACK
}
  • RBTree类
public class RBTree {
    private final Node NIL = new Node(null, null, null, Color.BLACK, -1);
    private Node root;
    public RBTree() {
        root = NIL;
    }
    public RBTree(Node root) {
        this.root = root;
    }
    //插入节点
    public void rbInsert(Node node) {
        Node previous = NIL;
        Node temp = root;
        while (temp != NIL) {
            previous = temp;
            if (temp.getValue() < node.getValue()) {
                temp = temp.getRight();
            } else {
                temp = temp.getLeft();
            }
        }
        node.setParent(previous);
        if (previous == NIL) {
            root = node;
            root.setParent(NIL);
        } else if (previous.getValue() > node.getValue()) {
            previous.setLeft(node);
        } else {
            previous.setRight(node);
        }
        node.setLeft(NIL);
        node.setRight(NIL);
        node.setColor(Color.RED);
        rb_Insert_Fixup(node);
    }
    //插入节点后的调整
    private void rb_Insert_Fixup(Node node) {
        while (node.getParent().getColor() == Color.RED) {
            if (node.getParent() == node.getParent().getParent().getLeft()) {
                Node rightNuncle = node.getParent().getParent().getRight();
                if (rightNuncle.getColor() == Color.RED) { //Case 1
                    rightNuncle.setColor(Color.BLACK);
                    node.getParent().setColor(Color.BLACK);
                    node.getParent().getParent().setColor(Color.RED);
                    node = node.getParent().getParent();
                } else if (node == node.getParent().getRight()) { //case 2
                    node = node.getParent();
                    leftRotate(node);
                } else { //case 3
                    node.getParent().setColor(Color.BLACK);
                    node.getParent().getParent().setColor(Color.RED);
                    rightRotate(node.getParent().getParent());
                }
            } else {
                Node leftNuncle = node.getParent().getParent().getLeft();
                if (leftNuncle.getColor() == Color.RED) { //case 4
                    leftNuncle.setColor(Color.BLACK);
                    node.getParent().setColor(Color.BLACK);
                    node.getParent().getParent().setColor(Color.RED);
                    node = node.getParent().getParent();
                } else if (node == node.getParent().getLeft()) { //case 5
                    node = node.getParent();
                    rightRotate(node);
                } else { // case 6
                    node.getParent().setColor(Color.BLACK);
                    node.getParent().getParent().setColor(Color.RED);
                    leftRotate(node.getParent().getParent());
                }
            }
        }
        root.setColor(Color.BLACK);
    }
    //删除节点
    public Node rbDelete(int data) {
        Node node = search(data);
        Node temp = NIL;
        Node child = NIL;
        if (node == null) {
            return null;
        } else {
            if (node.getLeft() == NIL || node.getRight() == NIL) {
                temp = node;
            } else {
                temp = successor(node);
            }
            if (temp.getLeft() != NIL) {
                child = temp.getLeft();
            } else {
                child = temp.getRight();
            }
            child.setParent(temp.getParent());
            if (temp.getParent() == NIL) {
                root = child;
            } else if (temp == temp.getParent().getLeft()) {
                temp.getParent().setLeft(child);
            } else {
                temp.getParent().setRight(child);
            }
            if (temp != node) {
                node.setValue(temp.getValue());
            }
            if (temp.getColor() == Color.BLACK) {
                rb_Delete_Fixup(child);
            }
            return temp;
        }
    }
    //删除节点后的调整
    private void rb_Delete_Fixup(Node node) {
        while (node != root && node.getColor() == Color.BLACK) {
            if (node == node.getParent().getLeft()) {
                Node rightBrother = node.getParent().getRight();
                if (rightBrother.getColor() == Color.RED) { //case 1 node节点为左孩子,node节点的兄弟为RED
                    rightBrother.setColor(Color.BLACK);
                    node.getParent().setColor(Color.RED);
                    leftRotate(node.getParent());
                    rightBrother = node.getParent().getRight();
                }
                if (rightBrother.getLeft().getColor() == Color.BLACK && rightBrother.getRight().getColor() == Color.BLACK) {
                    rightBrother.setColor(Color.RED);
                    node = node.getParent();
                } else if (rightBrother.getRight().getColor() == Color.BLACK) {
                    rightBrother.getLeft().setColor(Color.BLACK);
                    rightBrother.setColor(Color.RED);
                    rightRotate(rightBrother);
                    rightBrother = node.getParent().getRight();
                } else {
                    rightBrother.setColor(node.getParent().getColor());
                    node.getParent().setColor(Color.BLACK);
                    rightBrother.getRight().setColor(Color.BLACK);
                    leftRotate(node.getParent());
                    node = root;
                }
            } else {
                Node leftBrother = node.getParent().getLeft();
                if (leftBrother.getColor() == Color.RED) {
                    leftBrother.setColor(Color.BLACK);
                    node.getParent().setColor(Color.RED);
                    rightRotate(node.getParent());
                    leftBrother = node.getParent().getLeft();
                }
                if (leftBrother.getLeft().getColor() == Color.BLACK && leftBrother.getRight().getColor() == Color.BLACK) {
                    leftBrother.setColor(Color.RED);
                    node = node.getParent();
                } else if (leftBrother.getLeft().getColor() == Color.BLACK) {
                    leftBrother.setColor(Color.RED);
                    leftBrother.getRight().setColor(Color.BLACK);
                    leftRotate(leftBrother);
                    leftBrother = node.getParent().getLeft();
                } else {
                    leftBrother.setColor(node.getParent().getColor());
                    node.getParent().setColor(Color.BLACK);
                    leftBrother.getLeft().setColor(Color.BLACK);
                    rightRotate(node.getParent());
                    node = root;
                }
            }
        }
        node.setColor(Color.BLACK);
    }
    //查找节点node的后继节点
    public Node successor(Node node) {
        Node rightChild = node.getRight();
        if (rightChild != NIL) {
            Node previous = null;
            while (rightChild != NIL) {
                previous = rightChild;
                rightChild = rightChild.getLeft();
            }
            return previous;
        } else {
            Node parent = node.getParent();
            while (parent != NIL && node != parent.getLeft()) {
                node = parent;
                parent = parent.getParent();
            }
            return parent;
        }
    }
    //查找节点
    public Node search(int data) {
        Node temp = root;
        while (temp != NIL) {
            if (temp.getValue() == data) {
                return temp;
            } else if (data < temp.getValue()) {
                temp = temp.getLeft();
            } else {
                temp = temp.getRight();
            }
        }
        return null;
    }
    //左转函数
    private void leftRotate(Node node) {
        Node rightNode = node.getRight();
        node.setRight(rightNode.getLeft());
        if (rightNode.getLeft() != NIL) {
            rightNode.getLeft().setParent(node);
        }
        rightNode.setParent(node.getParent());
        if (node.getParent() == NIL) {
            rightNode = root;
        } else if (node == node.getParent().getLeft()) {
            node.getParent().setLeft(rightNode);
        } else {
            node.getParent().setRight(rightNode);
        }
        rightNode.setLeft(node);
        node.setParent(rightNode);
    }
    //右转函数
    private void rightRotate(Node node) {
        Node leftNode = node.getLeft();
        node.setLeft(leftNode.getRight());
        if (leftNode.getRight() != null) {
            leftNode.getRight().setParent(node);
        }
        leftNode.setParent(node.getParent());
        if (node.getParent() == NIL) {
            root = leftNode;
        } else if (node == node.getParent().getLeft()) {
            node.getParent().setLeft(leftNode);
        } else {
            node.getParent().setRight(leftNode);
        }
        leftNode.setRight(node);
        node.setParent(leftNode);
    }
    //中序遍历红黑树
    public void printTree() {
        inOrderTraverse(root);
    }
    private void inOrderTraverse(Node node) {
        if (node != NIL) {
            inOrderTraverse(node.getLeft());
            System.out.println(" 节点:" + node.getValue() + "的颜色为:" + node.getColor());
            inOrderTraverse(node.getRight());
        }
    }
    public Node getNIL() {
        return NIL;
    }
}
  • RBTreeTest测试类
public class RBTreeTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        RBTree rbTree = new RBTree();
        rbTree.rbInsert(new Node(41));
        rbTree.rbInsert(new Node(38));
        rbTree.rbInsert(new Node(31));
        rbTree.rbInsert(new Node(12));
        rbTree.rbInsert(new Node(19));
        rbTree.rbInsert(new Node(8));
        //rbTree.printTree();
        rbTree.rbDelete(19);
        rbTree.printTree();
    }
}
    原文作者:红黑树
    原文地址: https://my.oschina.net/ytqvip/blog/750616
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞