喵星之旅-沉睡的猫咪-红黑树

本文建立在两个基础之上:1、会基本的java编程;2、对二叉树是认识的

具体的分类情况分析参看最下方视频连接:初级算法部分

红黑树概念

当一颗二叉树符合了如下要求后,就称之为红黑树:

1、节点具有颜色,只有红色或者黑色,只能是唯一颜色

2、二叉树是有序的,即每一个节点的左节点存值都比当前节点值小,右节点值比当前节点值不小

3、根结点和叶子节点为黑色,叶子节点值的是树的末端没有子节点的节点下一层,是不存有值的,叶子节点是空节点

4、如果一个节点是红色的,父节点必须是黑色的,也就是不存在连续的双红

5、对于黑色节点完全平衡,即从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树java实现

1、前置工作

创建一个树类

 

public class RBTree{
    private static final boolean RED = false;
    private static final boolean BLACK = true;
    private RBTreeNode root;
}

 

创建节点类

 

private static class RBTreeNode {
        private int value;
        private RBTreeNode up;
        private RBTreeNode left;
        private RBTreeNode right;
        private boolean color;
}

 

节点类中编写遍历方法,方便bug查询和结果展示

 

        public void show(int count, String lor) {
            String s = "";
            for (int i = 0; i < count; i++) {
                s += "        ";
            }
            s += lor + "[value=" + value + ", color=" + color + "]";
            System.out.println(s);
            if (left != null) {
                left.show(count + 1, "l");
            }
            if (right != null) {
                right.show(count + 1, "r");
            }
        }        

 

2、插入,由于旋转操作是针对于一般化的二叉树操作,只是方便复用,不会造成效率提升(无论这里的编码还是执行),这里不再封装左右旋转方法,针对红黑树直接处理。

 

/**
     *  添加节点
     * @param n
     */
    public void add(int n) {
        // 创建红色节点
        RBTreeNode node = new RBTreeNode(n);
        // 查找要插入的位置,并且插入
        insert(node, n);
        // 调整双红问题
        tobalance(node);
    }

 

    private void insert(RBTreeNode node, int n) {
        RBTreeNode p = this.root;
        if (p == null) {
            this.root = node;
            return;
        }
        for (;;) {
            if (p.value > n) {
                if (p.left == null) {
                    p.left = node;
                    node.up = p;
                    break;
                } else {
                    p = p.left;
                    continue;
                }
            } else {
                if (p.right == null) {
                    p.right = node;
                    node.up = p;
                    break;
                } else {
                    p = p.right;
                    continue;
                }
            }
        }
    }
    /**
     *  调整双红问题
     * @param node
     */
    private void tobalance(RBTreeNode node) {
        RBTreeNode now = node;
        RBTreeNode up = null;
        RBTreeNode upup = null;
        RBTreeNode top = null;
        RBTreeNode n1 = null;
        RBTreeNode n2 = null;
        RBTreeNode n3 = null;
        RBTreeNode n4 = null;
        // 获得分类情况
        for (boolean flag = true; flag;) {
            int n = sortForInsert(now);
            switch (n) {//含义参看上面方法说明
            case 1:
                now.color = RBTree.BLACK;
                flag = false;
                
                break;
            case 2:
                flag = false;
                
                break;
            case 3:
                up = now.up;
                upup = up.up;
                upup.color = RBTree.RED;
                upup.left.color = RBTree.BLACK;
                upup.right.color = RBTree.BLACK;
                now = upup;
                
                break;

            case 4:
                up = now.up;
                upup = up.up;
                upup.color = RBTree.RED;
                upup.left.color = RBTree.BLACK;
                upup.right.color = RBTree.BLACK;
                now = upup;
                
                break;
            case 5:
                up = now.up;
                upup = up.up;
                n1 = up.right;
                n2 = upup.right;
                top = upup.up;
                
                up.color = RBTree.BLACK;
                upup.color = RBTree.RED;
                
                up.right = upup;
                upup.up = up;
                upup.left = n1;
                if (n1 != null) {
                    n1.up = upup;
                }
                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                if (top == null) {
                    root = up;
                    root.up = null;
                } else {
                    up.up = top;
                    if (top.left == upup) {
                        top.left = up;
                    } else {
                        top.right = up;
                    }
                }
                flag = false;
                
                break;
            case 6:
                up = now.up;
                upup = up.up;
                
                top = upup.up;
                n1 = up.left;
                n2 = now.left;
                n3 = now.right;
                n4 = upup.right;
                
                now.color = RBTree.BLACK;
                upup.color = RBTree.RED;
                
                up.right = n2;
                if (n2 !=null) {
                    n2.up = up;
                }
                up.up = now;
                now.left = up;
                now.right = upup;
                upup.up = now;
                upup.left = n3;
                if (n3 != null) {
                    n3.up = upup;
                }
                if (top == null) {
                    root = now;
                    root.up = null;
                } else {
                    now.up = top;
                    if (top.left == upup) {
                        top.left = now;
                    } else {
                        top.right = now;
                    }
                }
                flag = false;
                
                break;
            case 7:
                up = now.up;
                upup = up.up;
                top = upup.up;
                n2 = now.left;
                n3 = now.right;
                now.color = RBTree.BLACK;
                upup.color = RBTree.RED;
                
                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                upup.up = now;
                now.left = upup;
                up.up = now;
                now.right = up;
                up.left = n3;
                if (n3 != null) {
                    n3.up = up;
                }
                if (top == null) {
                    root = now;
                    root.up = null;
                } else {
                    now.up = top;
                    if (top.left == upup) {
                        top.left = now;
                    } else {
                        top.right = now;
                    }
                }
                flag = false;
                
                break;
            case 8:
                up = now.up;
                upup = up.up;
                top = upup.up;
                n2 = up.left;
                up.color = RBTree.BLACK;
                upup.color = RBTree.RED;
                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                upup.up = up;
                up.left = upup;

                if (top == null) {
                    root = up;
                    root.up = null;
                } else {
                    up.up = top;
                    if (top.left == upup) {
                        top.left = up;
                    } else {
                        top.right = up;
                    }
                }
                flag = false;
                
                break;
            }
        }
        root.color = RBTree.BLACK;
    }
View Code
    /**
     *  对于插入操作,判断分类情况
     * @param node
     * @return 分类情况:1-根结点,2-父节点黑色, 3-叔叔节点红色,父节点红色,父节点是左节点,4-叔叔节点红色,父节点红色,父节点是右节点,
     *         5-叔叔节点不是红色,父节点红色,父节点是左节点,当前节点是父节点左孩子,6-叔叔节点不是红色,父节点红色,父节点是左节点,当前节点是父节点右孩子,
     *         7-叔叔节点不是红色,父节点红色,父节点是 右节点,当前节点是父节点左孩子,8-叔叔节点不是红色,父节点红色,父节点是
     *         右节点,当前节点是父节点右孩子
     */
    private int sortForInsert(RBTreeNode node) {
        if (node.up == null) {
            return 1;
        } else if (node.up.color == RBTree.BLACK) {
            return 2;
        } else {
            RBTreeNode up = node.up;
            RBTreeNode upup = up.up;
            if (up == upup.left) {// 父节点是左节点
                if (upup.right == null || upup.right.color == RBTree.BLACK) {
                    if (up.left == node) {
                        return 5;
                    } else {
                        return 6;
                    }
                } else {
                    return 3;
                }
            } else {// 父节点是右节点
                if (upup.left == null || upup.left.color == RBTree.BLACK) {
                    if (up.left == node) {
                        return 7;
                    } else {
                        return 8;
                    }
                } else {
                    return 4;
                }
            }
        }

    }

3、删除

 

/**
     * 
     * 删除节点,如果存在相同值,随便删除一个
     * 
     * @param n
     */
    public void remove(int n) {
        // 找到要删除的节点
        RBTreeNode del = findNode(n);
        if (del == null) {
            return;
        }
        // 删除节点,并返回待处理节点,如过不存在双黑色,则返回null
        RBTreeNode doubleBlack = del(del);
        if (doubleBlack == null) {
            return;
        }
        // 处理双黑
        RBTreeNode d = doubleBlack;
        fixdoubleBlack(doubleBlack);
        if (d.up.left == d) {
            d.up.left = null;
        } else {
            d.up.right = null;
        }

    }

 

    /**
     * 查找
     * 
     * @param n
     * @return
     */
    private RBTreeNode findNode(int n) {

        RBTreeNode p = this.root;
        for (;;) {
            if (p == null) {
                return null;
            }
            if (p.value == n) {
                return p;
            } else {
                if (p.value < n) {
                    p = p.right;
                } else {
                    p = p.left;
                }
            }
        }

    }
/**
     * 删除节点,并返回有双黑色问题的节点
     * 
     * @param del
     * @return
     */
    private RBTreeNode del(RBTreeNode del) {
        // 右两个子节点的转化成有值多一个子节点
        if (del.left != null && del.right != null) {
            RBTreeNode p = findMax(del.left);
            del.value = p.value;
            del = p;
        }

        RBTreeNode top = del.up;
        if (del.left == null && del.right == null) {
            if (top == null) {
                root = null;
                return null;
            }

            if (del.color == RED) {
                if (top.left == del) {
                    top.left = null;
                } else {
                    top.right = null;
                }
                return null;
            } else {
                return del;
            }
        } else if (del.left != null && del.right == null) {
            del.left.color = BLACK;
            del.left.up = top;
            if (top == null) {
                root = del.left;
            }
            if (top.left == del) {
                top.left = del.left;
            } else {
                top.right = del.left;
            }
            return null;
        } else if (del.left == null && del.right != null) {
            del.right.color = BLACK;
            del.right.up = top;
            if (top == null) {
                root = del.right;
            }
            if (top.left == del) {
                top.left = del.right;
            } else {
                top.right = del.right;
            }
            return null;
        }
        return null;
    }
    /**
     * 分类讨论双黑问题
     * 
     * @param doubleBlack
     */
    private void fixdoubleBlack(RBTreeNode doubleBlack) {

        for (boolean f = true; f;) {

            RBTreeNode up = doubleBlack.up;
            RBTreeNode top = null;
            RBTreeNode b = null;// 兄弟节点
            RBTreeNode bl = null;// 兄弟节点左子节点
            RBTreeNode br = null;// 兄弟节点右子节点
            RBTreeNode n1 = null;
            RBTreeNode n2 = null;

            int n = sortForDel(doubleBlack);
            switch (n) {
            case 1:
                f = false;
                break;
            case 2:
                up.color = BLACK;
                if (doubleBlack == up.left) {
                    up.right.color = RED;
                } else {
                    up.left.color = RED;
                }
                f = false;
                break;
            case 3:
                if (doubleBlack == up.left) {
                    up.right.color = RED;
                } else {
                    up.left.color = RED;
                }
                doubleBlack = up;
                break;
            case 4:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;

                b.color = BLACK;
                up.color = RED;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }
                b.right = up;
                up.up = b;
                up.left = br;
                if (br != null) {

                    br.up = up;
                }

                break;
            case 5:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;

                if (bl != null) {
                    bl.color = BLACK;
                }
                b.color = up.color;
                up.color = BLACK;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }
                b.right = up;
                up.up = b;
                if (br != null) {
                    br.up = up;

                }
                up.left = br;
                f = false;
                break;
            case 6:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;
                n1 = br.left;
                n2 = br.right;

                br.color = up.color;
                up.color = BLACK;

                br.up = top;
                if (top == null) {
                    root = br;
                } else {
                    if (top.left == up) {
                        top.left = br;
                    } else {
                        top.right = br;
                    }
                }
                br.left = b;
                b.up = br;
                br.right = up;
                up.up = br;
                b.right = n1;

          if (n1 != null) {

            n1.up = b;
           }
          up.left = n2;
          if (n2 != null) {

            n2.up = up;
            }


                f = false;
                break;
            case 7:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;

                b.color = BLACK;
                up.color = RED;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }

                b.left = up;
                up.up = b;
                up.right = bl;
                if (bl != null) {
                    bl.up = up;
                    
                }

                break;
            case 8:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;

                br.color = BLACK;
                b.color = up.color;
                up.color = BLACK;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }

                b.left = up;
                up.up = b;
                up.right = bl;
                if (bl != null) {
                    bl.up = up;
                    
                }

                f = false;
                break;
            case 9:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;
                n1 = bl.left;
                n2 = bl.right;
                bl.color = up.color;
                up.color = BLACK;

                bl.up = top;
                if (top == null) {
                    root = bl;
                } else {
                    if (top.left == up) {
                        top.left = bl;
                    } else {
                        top.right = bl;
                    }
                }
                br.left = up;
                br.right = b;
                up.up = br;
                b.up = br;
                up.right = n1;

          if (n1 != null) {

          n1.up = up;
          }
          b.left = n2;
          if (n2 != null) {

          n2.up = b;
          }



                f = false;
                break;

            }

        }

    }
    /**
     * 
     * @param doubleBlack
     * @return
     * 
     *         1、双黑节点为根结点
     * 
     *         2、兄弟节点和其子节点都为黑色,并且父节点红色
     * 
     *         3、兄弟节点和其子节点都为黑色,并且父节点黑色
     * 
     *         4、兄弟节点为左节点,兄弟节点红色
     * 
     *         5、兄弟节点为左节点,左子节点红色,右子节点无所谓
     * 
     *         6、兄弟节点为左节点,左子节点黑色,右子节点红色
     * 
     *         7、兄弟节点为右节点,兄弟红色,
     * 
     *         8、兄弟节点为右节点,右子节点红色,左子节点无所谓
     * 
     *         9、兄弟节点为右节点,右子节点黑色,左子节点红色
     */
    private int sortForDel(RBTreeNode doubleBlack) {
        RBTreeNode up = doubleBlack.up;// 父节点
        RBTreeNode b = null;// 兄弟节点
        RBTreeNode bl = null;// 兄弟节点左子节点
        RBTreeNode br = null;// 兄弟节点右子节点
        if (up == null) {
            return 1;
        }
        if (up.left == doubleBlack) {
            b = up.right;
            bl = b.left;
            br = b.right;
            if (b.color == BLACK && (bl == null || bl.color == BLACK) && (br == null || br.color == BLACK)) {
                if (up.color == RED) {
                    return 2;
                } else {
                    return 3;
                }
            } else if (b.color == RED) {
                return 7;
            } else if (br != null && br.color == RED) {
                return 8;
            } else {
                return 9;
            }
        } else {
            b = up.left;
            bl = b.left;
            br = b.right;

            if (b.color == BLACK && (bl == null || bl.color == BLACK) && (br == null || br.color == BLACK)) {
                if (up.color == RED) {
                    return 2;
                } else {
                    return 3;
                }
            } else if (b.color == RED) {
                return 4;
            } else if (bl != null && bl.color == RED) {
                return 5;
            } else {
                return 6;
            }
        }

    }

 

 

 

测试结果

 

package club.kittybunn.test;

import club.kittybunny.RBTree;

public class Test {
    public static void main(String[] args) {
        RBTree tree = new RBTree();
        tree.add(1);
        tree.add(2);
        tree.add(3);
        tree.add(4);
        tree.add(5);
        tree.add(6);
        tree.add(7);
        tree.add(8);
        tree.add(9);
        tree.add(10);

        tree.show(0, "");
        tree.remove(4);
        tree.show(0, "");
        tree.remove(7);
        tree.show(0, "");

    }
}

 

 

 

 


最终完整代码

 

package club.kittybunny;

import java.util.TreeMap;

import javax.sound.sampled.ReverbType;

/**
 * 
 * @author bunny~~我是兔子我会喵,我叫喵星兔。
 *
 */
public class RBTree {
    private static final boolean RED = false;
    private static final boolean BLACK = true;
    private RBTreeNode root;

    /**
     * 添加节点
     * 
     * @param n
     */
    public void add(int n) {
        // 创建红色节点
        RBTreeNode node = new RBTreeNode(n);
        // 查找要插入的位置,并且插入
        insert(node, n);
        // 调整双红问题
        tobalance(node);
    }

    /**
     * 
     * 删除节点,如果存在相同值,随便删除一个
     * 
     * @param n
     */
    public void remove(int n) {
        // 找到要删除的节点
        RBTreeNode del = findNode(n);
        if (del == null) {
            return;
        }
        // 删除节点,并返回待处理节点,如过不存在双黑色,则返回null
        RBTreeNode doubleBlack = del(del);
        if (doubleBlack == null) {
            return;
        }
        // 处理双黑
        RBTreeNode d = doubleBlack;
        fixdoubleBlack(doubleBlack);
        if (d.up.left == d) {
            d.up.left = null;
        } else {
            d.up.right = null;
        }

    }

    /**
     * 分类讨论双黑问题
     * 
     * @param doubleBlack
     */
    private void fixdoubleBlack(RBTreeNode doubleBlack) {

        for (boolean f = true; f;) {

            RBTreeNode up = doubleBlack.up;
            RBTreeNode top = null;
            RBTreeNode b = null;// 兄弟节点
            RBTreeNode bl = null;// 兄弟节点左子节点
            RBTreeNode br = null;// 兄弟节点右子节点
            RBTreeNode n1 = null;
            RBTreeNode n2 = null;

            int n = sortForDel(doubleBlack);
            switch (n) {
            case 1:
                f = false;
                break;
            case 2:
                up.color = BLACK;
                if (doubleBlack == up.left) {
                    up.right.color = RED;
                } else {
                    up.left.color = RED;
                }
                f = false;
                break;
            case 3:
                if (doubleBlack == up.left) {
                    up.right.color = RED;
                } else {
                    up.left.color = RED;
                }
                doubleBlack = up;
                break;
            case 4:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;

                b.color = BLACK;
                up.color = RED;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }
                b.right = up;
                up.up = b;
                up.left = br;
                if (br != null) {

                    br.up = up;
                }

                break;
            case 5:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;

                if (bl != null) {
                    bl.color = BLACK;
                }
                b.color = up.color;
                up.color = BLACK;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }
                b.right = up;
                up.up = b;
                if (br != null) {
                    br.up = up;

                }
                up.left = br;
                f = false;
                break;
            case 6:
                top = up.up;
                b = up.left;
                bl = b.left;
                br = b.right;
                n1 = br.left;
                n2 = br.right;

                br.color = up.color;
                up.color = BLACK;

                br.up = top;
                if (top == null) {
                    root = br;
                } else {
                    if (top.left == up) {
                        top.left = br;
                    } else {
                        top.right = br;
                    }
                }
                br.left = b;
                b.up = br;
                br.right = up;
                up.up = br;
                b.right = n1;

          if (n1 != null) {

          n1.up = b;
          }
          up.left = n2;
          if (n2 != null) {

          n2.up = up;
          }


                f = false;
                break;
            case 7:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;

                b.color = BLACK;
                up.color = RED;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }

                b.left = up;
                up.up = b;
                up.right = bl;
                if (bl != null) {
                    bl.up = up;
                    
                }

                break;
            case 8:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;

                br.color = BLACK;
                b.color = up.color;
                up.color = BLACK;

                b.up = top;
                if (top == null) {
                    root = b;
                } else {
                    if (top.left == up) {
                        top.left = b;
                    } else {
                        top.right = b;
                    }
                }

                b.left = up;
                up.up = b;
                up.right = bl;
                if (bl != null) {
                    bl.up = up;
                    
                }

                f = false;
                break;
            case 9:
                top = up.up;
                b = up.right;
                bl = b.left;
                br = b.right;
                n1 = bl.left;
                n2 = bl.right;
                bl.color = up.color;
                up.color = BLACK;

                bl.up = top;
                if (top == null) {
                    root = bl;
                } else {
                    if (top.left == up) {
                        top.left = bl;
                    } else {
                        top.right = bl;
                    }
                }
                br.left = up;
                br.right = b;
                up.up = br;
                b.up = br;
                up.right = n1;

          if (n1 != null) {

          n1.up = up;
          }
          b.left = n2;
          if (n2 != null) {

          n2.up = b;
          }



                f = false;
                break;

            }

        }

    }

    /**
     * 
     * @param doubleBlack
     * @return
     * 
     *         1、双黑节点为根结点
     * 
     *         2、兄弟节点和其子节点都为黑色,并且父节点红色
     * 
     *         3、兄弟节点和其子节点都为黑色,并且父节点黑色
     * 
     *         4、兄弟节点为左节点,兄弟节点红色
     * 
     *         5、兄弟节点为左节点,左子节点红色,右子节点无所谓
     * 
     *         6、兄弟节点为左节点,左子节点黑色,右子节点红色
     * 
     *         7、兄弟节点为右节点,兄弟红色,
     * 
     *         8、兄弟节点为右节点,右子节点红色,左子节点无所谓
     * 
     *         9、兄弟节点为右节点,右子节点黑色,左子节点红色
     */
    private int sortForDel(RBTreeNode doubleBlack) {
        RBTreeNode up = doubleBlack.up;// 父节点
        RBTreeNode b = null;// 兄弟节点
        RBTreeNode bl = null;// 兄弟节点左子节点
        RBTreeNode br = null;// 兄弟节点右子节点
        if (up == null) {
            return 1;
        }
        if (up.left == doubleBlack) {
            b = up.right;
            bl = b.left;
            br = b.right;
            if (b.color == BLACK && (bl == null || bl.color == BLACK) && (br == null || br.color == BLACK)) {
                if (up.color == RED) {
                    return 2;
                } else {
                    return 3;
                }
            } else if (b.color == RED) {
                return 7;
            } else if (br != null && br.color == RED) {
                return 8;
            } else {
                return 9;
            }
        } else {
            b = up.left;
            bl = b.left;
            br = b.right;

            if (b.color == BLACK && (bl == null || bl.color == BLACK) && (br == null || br.color == BLACK)) {
                if (up.color == RED) {
                    return 2;
                } else {
                    return 3;
                }
            } else if (b.color == RED) {
                return 4;
            } else if (bl != null && bl.color == RED) {
                return 5;
            } else {
                return 6;
            }
        }

    }

    /**
     * 删除节点,并返回有双黑色问题的节点
     * 
     * @param del
     * @return
     */
    private RBTreeNode del(RBTreeNode del) {
        // 右两个子节点的转化成有值多一个子节点
        if (del.left != null && del.right != null) {
            RBTreeNode p = findMax(del.left);
            del.value = p.value;
            del = p;
        }

        RBTreeNode top = del.up;
        if (del.left == null && del.right == null) {
            if (top == null) {
                root = null;
                return null;
            }

            if (del.color == RED) {
                if (top.left == del) {
                    top.left = null;
                } else {
                    top.right = null;
                }
                return null;
            } else {
                return del;
            }
        } else if (del.left != null && del.right == null) {
            del.left.color = BLACK;
            del.left.up = top;
            if (top == null) {
                root = del.left;
            }
            if (top.left == del) {
                top.left = del.left;
            } else {
                top.right = del.left;
            }
            return null;
        } else if (del.left == null && del.right != null) {
            del.right.color = BLACK;
            del.right.up = top;
            if (top == null) {
                root = del.right;
            }
            if (top.left == del) {
                top.left = del.right;
            } else {
                top.right = del.right;
            }
            return null;
        }
        return null;
    }

    /**
     * 找出当前节点往下的范围内最大值的节点
     * 
     * @param node
     * @return
     */
    private RBTreeNode findMax(RBTreeNode node) {
        RBTreeNode p = node;
        for (;;) {
            if (p.right == null) {
                return p;
            } else {
                p = p.right;
            }
        }
    }

    /**
     * 查找
     * 
     * @param n
     * @return
     */
    private RBTreeNode findNode(int n) {

        RBTreeNode p = this.root;
        for (;;) {
            if (p == null) {
                return null;
            }
            if (p.value == n) {
                return p;
            } else {
                if (p.value < n) {
                    p = p.right;
                } else {
                    p = p.left;
                }
            }
        }

    }

    /**
     * 调整双红问题
     * 
     * @param node
     */
    private void tobalance(RBTreeNode node) {
        RBTreeNode now = node;
        RBTreeNode up = null;
        RBTreeNode upup = null;
        RBTreeNode top = null;
        RBTreeNode n1 = null;
        RBTreeNode n2 = null;
        RBTreeNode n3 = null;
        RBTreeNode n4 = null;
        // 获得分类情况
        for (boolean flag = true; flag;) {
            int n = sortForInsert(now);
            switch (n) {// 含义参看上面方法说明
            case 1:
                now.color = RBTree.BLACK;
                flag = false;

                break;
            case 2:
                flag = false;

                break;
            case 3:
                up = now.up;
                upup = up.up;
                upup.color = RBTree.RED;
                upup.left.color = RBTree.BLACK;
                upup.right.color = RBTree.BLACK;
                now = upup;

                break;

            case 4:
                up = now.up;
                upup = up.up;
                upup.color = RBTree.RED;
                upup.left.color = RBTree.BLACK;
                upup.right.color = RBTree.BLACK;
                now = upup;

                break;
            case 5:
                up = now.up;
                upup = up.up;
                n1 = up.right;
                n2 = upup.right;
                top = upup.up;

                up.color = RBTree.BLACK;
                upup.color = RBTree.RED;

                up.right = upup;
                upup.up = up;
                upup.left = n1;
                if (n1 != null) {
                    n1.up = upup;
                }
                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                if (top == null) {
                    root = up;
                    root.up = null;
                } else {
                    up.up = top;
                    if (top.left == upup) {
                        top.left = up;
                    } else {
                        top.right = up;
                    }
                }
                flag = false;

                break;
            case 6:
                up = now.up;
                upup = up.up;

                top = upup.up;
                n1 = up.left;
                n2 = now.left;
                n3 = now.right;
                n4 = upup.right;

                now.color = RBTree.BLACK;
                upup.color = RBTree.RED;

                up.right = n2;
                if (n2 != null) {
                    n2.up = up;
                }
                up.up = now;
                now.left = up;
                now.right = upup;
                upup.up = now;
                upup.left = n3;
                if (n3 != null) {
                    n3.up = upup;
                }
                if (top == null) {
                    root = now;
                    root.up = null;
                } else {
                    now.up = top;
                    if (top.left == upup) {
                        top.left = now;
                    } else {
                        top.right = now;
                    }
                }
                flag = false;

                break;
            case 7:
                up = now.up;
                upup = up.up;
                top = upup.up;
                n2 = now.left;
                n3 = now.right;
                now.color = RBTree.BLACK;
                upup.color = RBTree.RED;

                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                upup.up = now;
                now.left = upup;
                up.up = now;
                now.right = up;
                up.left = n3;
                if (n3 != null) {
                    n3.up = up;
                }
                if (top == null) {
                    root = now;
                    root.up = null;
                } else {
                    now.up = top;
                    if (top.left == upup) {
                        top.left = now;
                    } else {
                        top.right = now;
                    }
                }
                flag = false;

                break;
            case 8:
                up = now.up;
                upup = up.up;
                top = upup.up;
                n2 = up.left;
                up.color = RBTree.BLACK;
                upup.color = RBTree.RED;
                upup.right = n2;
                if (n2 != null) {
                    n2.up = upup;
                }
                upup.up = up;
                up.left = upup;

                if (top == null) {
                    root = up;
                    root.up = null;
                } else {
                    up.up = top;
                    if (top.left == upup) {
                        top.left = up;
                    } else {
                        top.right = up;
                    }
                }
                flag = false;

                break;
            }
        }
        root.color = RBTree.BLACK;
    }

    /**
     * 对于插入操作,判断分类情况
     * 
     * @param node
     * @return 分类情况:1-根结点,2-父节点黑色, 3-叔叔节点红色,父节点红色,父节点是左节点,4-叔叔节点红色,父节点红色,父节点是右节点,
     *         5-叔叔节点不是红色,父节点红色,父节点是左节点,当前节点是父节点左孩子,6-叔叔节点不是红色,父节点红色,父节点是左节点,当前节点是父节点右孩子,
     *         7-叔叔节点不是红色,父节点红色,父节点是 右节点,当前节点是父节点左孩子,8-叔叔节点不是红色,父节点红色,父节点是
     *         右节点,当前节点是父节点右孩子
     */
    private int sortForInsert(RBTreeNode node) {
        if (node.up == null) {
            return 1;
        } else if (node.up.color == RBTree.BLACK) {
            return 2;
        } else {
            RBTreeNode up = node.up;
            RBTreeNode upup = up.up;
            if (up == upup.left) {// 父节点是左节点
                if (upup.right == null || upup.right.color == RBTree.BLACK) {
                    if (up.left == node) {
                        return 5;
                    } else {
                        return 6;
                    }
                } else {
                    return 3;
                }
            } else {// 父节点是右节点
                if (upup.left == null || upup.left.color == RBTree.BLACK) {
                    if (up.left == node) {
                        return 7;
                    } else {
                        return 8;
                    }
                } else {
                    return 4;
                }
            }
        }

    }

    private void insert(RBTreeNode node, int n) {
        RBTreeNode p = this.root;
        if (p == null) {
            this.root = node;
            return;
        }
        for (;;) {
            if (p.value > n) {
                if (p.left == null) {
                    p.left = node;
                    node.up = p;
                    break;
                } else {
                    p = p.left;
                    continue;
                }
            } else {
                if (p.right == null) {
                    p.right = node;
                    node.up = p;
                    break;
                } else {
                    p = p.right;
                    continue;
                }
            }
        }
    }

    private static class RBTreeNode {
        private int value;
        private RBTreeNode up;
        private RBTreeNode left;
        private RBTreeNode right;
        private boolean color;

        /**
         * 颜色默认红色
         * 
         * @param value 节点值
         */
        public RBTreeNode(int value) {
            super();
            this.value = value;
            this.color = RBTree.RED;
        }

        /**
         * 
         * @param count 树深度
         * @param lor   是父节点的左还是右节点,l-左,r-右
         */
        public void show(int count, String lor) {
            String s = "";
            for (int i = 0; i < count; i++) {
                s += "        ";
            }
            s += lor + "[value=" + value + ", color=" + color + "]";
            System.out.println(s);
            if (left != null) {
                left.show(count + 1, "l");
            }
            if (right != null) {
                right.show(count + 1, "r");
            }
        }

    }

    public void show(int i, String string) {
        root.show(0, "");
    }
}

 

 

 

 

 

posted @ 2020-05-04 12:16  喵星兔  阅读(206)  评论(0编辑  收藏  举报