RedBlackTest.java

来源:互联网 发布:1980年电影 知乎 编辑:程序博客网 时间:2024/06/08 15:33
package tree;class RedBlackBST<Key extends Comparable<Key>,Value>{//与AVL树的建立有所不同,注意区别                                                     //后者不需要传入参数就可以进行递归调用,的确是一种方法    private static final boolean RED = true;    private static final boolean BLACK = false;    private class Node{        Key key;//键        Value val;//相关联的值        Node l,r;        int N;//这棵子树中的结点总数        boolean color;//当前节点与父节点之间链接的颜色        Node(Key key,Value val,int N,boolean color){            this.key = key;            this.val = val;            this.N = N;            this.color = color;        }    }    private boolean isRed(Node x){        if(x == null) return false;        return x.color == RED;//够简洁    }    private Node root;    public int size(){        return size(root);    }    private int size(Node x){//求的是结点个数        if(x==null) return 0;        else        return x.N;    }    private Node rotateLeft(Node h){//这些定义的局部操作有一个共同点就是说:保证没有平衡性        Node x = h.r;        h.r = x.l;        x.l = h;        x.color = RED;        x.N = h.N;        h.N = 1 + size(h.l) + size(h.r);        return x;    }    private Node rotateRight(Node h){        Node x = h.l;        h.l = x.r;        x.r = h;        x.color = h.color;        h.color = RED;        x.N = h.N;        h.N = 1 + size(h.l) + size(h.r);        return x;    }    private void flipColors(Node h){            h.color = RED;            h.l.color = BLACK;            h.r.color = BLACK;    }    //public void put(Node h,Key key,Value val){  只能通过参数的个数和类型实现多态,而通过返回类型是无法实现的    public void put(Key key,Value val){        root = put(root,key,val);        root.color = BLACK;    }    private Node put(Node h,Key key,Value val){        if(h == null)//指的就是建立一个新的结点            return new Node(key,val,1,RED);        int cmp = key.compareTo(h.key);//根据Key大小排的序,自上而下找到要插入的位置        if(cmp<0) h.l = put(h.l,key,val);        else if(cmp>0) h.r = put(h.r,key,val);        else h.val = val;//如果key相等,就相当于是修改,不会建立新的        //自下而上对每一个结点进行转换建立红黑树                                                                    (链接指的是:父结点和自己之间)        if(isRed(h.r) && !isRed(h.l)) h = rotateLeft(h);//原则1:不允许出现红色右链接        if(isRed(h.l) && isRed(h.l.l)) h = rotateRight(h);//原则2:左子和左孙都是红结点        if(isRed(h.l) && isRed(h.r)) flipColors(h);//原则3:左右链接都是红色的时候要将颜色向上翻转                                                   //这三步有执行的优先级        h.N = size(h.l) + size(h.r) + 1;        return h;    }    public void mid_trav(){        f(root);    }    private void f(Node node){        if(node == null) return;        f(node.l);        System.out.print(node.key+" ");        f(node.r);    }}public class RedBlackTest {    public static void main(String[] args) {        RedBlackBST<Integer,String> root = new RedBlackBST<Integer, String>();        root.put(3, "wo");        root.put(1, "ni");        root.put(2, "ta");        root.put(5, "ta");        root.put(4, "ta");        root.put(7, "ta");        System.out.println(root.size());        root.mid_trav();    }}