• 红黑树


    public class RedBlackBST<Key extends Comparable<Key>,value>
    {
        private Node root;
        private static final boolean RED = true;
        private static final boolean BLACK = false;
        private class Node
        {
            Key key;  
            Vlaue val;  //value是个啥?  似乎不需要。 我再看看 - -
            Node left,right,parent;
            boolean color;
    
            public Node(Key key, Vlaue val, Node parent,boolean color)
            {
                this.key = key;
                this.val = val;
                this.color = color;
            }
        }
            public Vlaue get(Key key)
            {
                Node x = root;
                while(x != null)
                {
                    int cmp = key.compareTo(x.key);
                    if(cmp < 0) x = x.left;
                    else if(cmp > 0) x = x.right;
                    else return x.val;
                }
                return null;
            }
    
            //插入节点
            public void put(Key key, Value value)
            {
                if(root == null) root = new Node(key, value, null, BLACK);
    
                //从根节点往下寻找合适的插入位置
                Node parent = null;   //查找位置,然后插入节点
                Node cur = root;
                //保持二叉树的特性,while循环寻找插入位置。插入位置肯定是null处
                while(cur != null)
                {
                    parent = cur;
                    if(key.compareTo(cur.key) > 0) cur = cur.right;
                    else cur = cur.left;
                }
    
                Node n = new Node(key, value, parent, RED);//普通的新建节点为红色
                //将新节点插入parent下
                if(key.compareTo(parent.key) > 0)parent.right = n;
                else parent.left = n;
    
                //插入新节点后要调整树中部分节点的颜色和属性来红黑树的特征不被破坏
                fixAfterInsertion(n);
    
            }
    
            private Node parentOf(Node x) {return x == null? null:x.parent;}
    
            private boolean colorOf(Node x){return x == null? null:x.color;}
        
            private Node leftOf(Node x){return x == null? null : x.left;}
    
            private Node rightOf(Node x){return x == null? null: x.right;}
    
            private void setColor(Node x, boolean color){if(x!=null) x.color = color;}
    
            //变色
            //不知道下面的case是怎么出来,应该是总结出来的
            private void fixAfterInsertion(Node x)
            {
                //父节点的颜色为红色
                while(x!=null && colorOf(parentOf(x)) == RED)
                {
                    //父节点的父节点
                    Node grandPa = parentOf(parentOf(x));
                    Node parent = parentOf(x);
    
                    //父节点是祖父节点的左孩子
                    if(parent == leftOf(grandPa)){
                        Node uncle = rightOf(grandPa);
                        //case1: 叔叔节点是红色
                        if(colorOf(uncle) == RED)
                        {
                            setColor(parent, BLACK);
                            setColor(uncle, BLACK);
                            setColor(grandPa, RED);
                            x = grandPa;  //这一步是为了之后的旋转
                        }else
                        {
                            //case2: 叔叔是黑色,且当前是右孩子
                            if(x == rightOf(parent))
                            {
                                x = parent;
                                rotateLeft(x);
                            }
    
                            //case3: 叔叔是黑色,且当前是左孩子
                            setColor(parent, BLACK);
                            setColor(grandPa, RED);
                            rotateRight(grandPa);
                        }
                    }
                    //父节点时祖父节点的右孩子
                    else
                    {
                        //case4: 叔叔节点时红色
                        Node uncle = leftOf(grandPa);
                        if(colorOf(uncle) ==  RED)
                        {
                            setColor(parent, BLACK);
                            setColor(uncle, BLACK);
                            setColor(grandPa, RED);
                            x= grandPa;
                                                }
                        //case5: 叔叔黑色,且当前是左孩子
                        else
                        {
                            if(x == leftOf(parent))
                            {
                                x = parent;
                                rotateRight(x)
                            }
                            //case6: 叔叔是黑色,且当前节点时右孩子
                            setColor(parent, BLACK);
                            setColor(grandPa,RED);
                            rotateLeft(grandPa);
                        }
                        
                    }
                }
                setColor(this.root, BLACK);
            }
            //左旋转, 右孩子升为根节点, 右孩子的左孩子左移
            //知道指针和链表这里就很好理解了
            public viod rotateLeft(Node x)
            {
                if(x == null) return;
                Node y = x.right;  //右孩子
                //建立旋转后的父子关系
                x.right = y.left;  //右孩子的左孩子变为变化后的x的右孩子
                if(y.left != null) y.left.parent = x;
                y.parent = x.parent;   //将x的parent赋值给y的parent .  
    
                if(x.parent == null) root = y;
                else if(x.parent.left == x) x.parent.left = y;
                else x.parent.right = y;
    
                y.left = x;  //将x设为y的左孩子
                x.parent = y; //将y设为x的parent
            }
    
            //右旋转  左孩子上升为根节点。左孩子的右孩子变为x的左孩子
            public void rotateRight(Node x)
            {
                if(x == null) rturn;
                Node y = x.left;
                x.left = y.right;
                if(y.right == null) y.right.parent = x;
                y.parent = x.parent;
    
                if(x.parent == null) root = y;
                else if(x.parent.left == x) x.parent.left = y;
                else x.parent.right = y;
    
                y.left = x;
                x.parent = y;
            }
        }
    }
  • 相关阅读:
    大型网站技术架构(七)网站的可扩展性架构
    【Spark深入学习 -15】Spark Streaming前奏-Kafka初体验
    结合案例深入解析模板方法设计模式
    android开发之自定义View 详解 资料整理 小冰原创整理,原创作品。
    1309:【例1.6】回文数(Noip1999)
    jQuery dataTables四种数据来源[转]
    CYQ.Data 轻量数据层之路 使用篇-MProc 存储过程与SQL 视频[最后一集] H (二十八)
    CRM系统项目总结
    同源策略:JSONP和CORS
    forms表单与modelfrom使用
  • 原文地址:https://www.cnblogs.com/GlazedCat/p/10549117.html
Copyright © 2020-2023  润新知