zoukankan      html  css  js  c++  java
  • 红黑树实现

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    
    public class RBTree<Key extends Comparable<Key>, Value> {
        enum color {Red, Black}
    
        private Node root;
    
        private class Node {
            private Key key;
            private Value val;
            private color color;
            private Node parent;
            private Node left_child, right_child;
            boolean isNIL = false;
    
            private Node(Key key, Value val, Node parent) {
                this.key = key;
                this.val = val;
                this.parent = parent;
                this.color = RBTree.color.Red;
                this.left_child = new Node(this);
                this.right_child = new Node(this);
            }
    
            private Node(Node parent) {
                this.color = RBTree.color.Black;
                this.isNIL = true;
                this.parent = parent;
            }
        }
    
        private void LevelOrder() {
            int h = 0;
            int num = 0;
            ArrayList<Node> t = new ArrayList<Node>();
            t.add(root);
            while (t.size() != 0) {
                int size = t.size();
                h++;
                System.out.println("第 " + h + " 层");
                for (int i = 0; i < size; i++) {
                    Node x = t.get(0);
                    num++;
                    if (x.left_child.parent != x)
                        System.out.println("Left");
                    if (x.right_child.parent != x)
                        System.out.println("Right");
                    System.out.print("   " + x.key + "-" + x.color + "  ");
                    if (!x.left_child.isNIL)
                        t.add(x.left_child);
                    if (!x.right_child.isNIL)
                        t.add(x.right_child);
                    t.remove(0);
                }
                System.out.println("");
            }
            System.out.println("共计" + num + "个数");
        }
    
        public void Insert(Key key, Value val) {
            if (root == null) {
                root = new Node(key, val, null);
                root.color = color.Black;
                return;
            }
            Node temp = root;
            while (true) {
                int cmp = key.compareTo(temp.key);
                if (cmp < 0)
                    if (!temp.left_child.isNIL)
                        temp = temp.left_child;
                    else {
                        temp.left_child = new Node(key, val, temp);
                        if (conflict(temp.left_child))
                            Update_Tree(temp.left_child);
                        return;
                    }
                else if (cmp > 0) {
                    if (!temp.right_child.isNIL)
                        temp = temp.right_child;
                    else {
                        temp.right_child = new Node(key, val, temp);
                        if (conflict(temp.right_child))
                            Update_Tree(temp.right_child);
                        return;
                    }
                } else {
                    temp.val = val;
                    return;
                }
            }
        }
    
        public void Remove(Key key) {
            Node temp = root;
            while (!temp.isNIL) {
                int cmp = key.compareTo(temp.key);
                if (cmp > 0)
                    temp = temp.right_child;
                else if (cmp < 0)
                    temp = temp.left_child;
                else {
                    if (isRoot(temp) && temp.left_child.isNIL && temp.right_child.isNIL) {
                        root = null;
                        return;
                    }
                    Node parent = temp.parent;
                    color t = temp.color;
                    if (!temp.left_child.isNIL && !temp.right_child.isNIL) {//当待删除节点的左右兄弟节点都不为空
                        Node x = temp.right_child;//找出后继节点
                        while (!x.left_child.isNIL)
                            x = x.left_child;
                        temp.key = x.key;
                        temp.val = x.val;
                        parent = x.parent;
                        t = x.color;
                        if (isLeftChild(x)) {
                            parent.left_child = x.right_child;
                            parent.left_child.parent = parent;
                            temp = parent.left_child;
                        } else {
                            parent.right_child = x.right_child;
                            parent.right_child.parent = parent;
                            temp = parent.right_child;
                        }
                    } else if (!temp.left_child.isNIL) {//当右兄弟为空
                        if (isLeftChild(temp)) {
                            if (isRoot(temp)) {
                                temp.key = temp.left_child.key;
                                temp.val = temp.left_child.val;
                                temp.left_child = temp.left_child.left_child;
                                temp.left_child.parent = temp;
                            } else {
                                parent.left_child = temp.left_child;
                                temp.left_child.parent = parent;
                                temp = parent.left_child;
                            }
                        } else {
                            parent.right_child = temp.left_child;
                            temp.left_child.parent = parent;
                            temp = parent.right_child;
                        }
                    } else if (!temp.right_child.isNIL) {//当左兄弟为空
                        if (isLeftChild(temp)) {
                            if (isRoot(temp)) {
                                temp.key = temp.right_child.key;
                                temp.val = temp.right_child.val;
                                temp.right_child = temp.right_child.left_child;
                                temp.right_child.parent = temp;
                            } else {
                                parent.left_child = temp.right_child;
                                temp.right_child.parent = parent;
                                temp = parent.left_child;
                            }
                        } else {
                            parent.right_child = temp.right_child;
                            temp.right_child.parent = parent;
                            temp = parent.right_child;
                        }
                    } else {                          //当左右兄弟都为空
                        if (isLeftChild(temp))
                            if (!isRoot(temp))
                                parent.left_child = temp.left_child;
                            else
                                parent.right_child = temp.left_child;
                        temp.left_child.parent = parent;
                        temp = temp.left_child;
                    }
                    if (t == color.Black)
                        if (temp.color == color.Red)
                            temp.color = color.Black;
                        else
                            Update_Tree_Remove(temp);
                }
            }
            while (root.parent != null)
                root = root.parent;
        }
    
        private void Update_Tree_Remove(Node temp) {
            if (isRoot(temp)) {
                if (!temp.left_child.isNIL && temp.left_child.color == color.Black)
                    temp.left_child.color = color.Red;
                else
                    temp.right_child.color = color.Red;
                return;
            }
            Node parent = temp.parent, uncle;
            if (isLeftChild(temp)) {
                uncle = parent.right_child;
                if (uncle.color == color.Black) {    //叔叔是黑色
                    if (uncle.left_child.color == color.Red || uncle.right_child.color == color.Red) {   //CASE 1 叔叔有一个孩子是红色的
                        color c = parent.color;
                        if (uncle.left_child.color == color.Red) {  //若叔叔的左孩子是红的
                            Node t = uncle.left_child;
                            temp = connect34(false, t, parent, uncle, parent, temp, t.left_child, t.right_child, uncle.right_child);
                            System.out.print("");
                        } else {                                    //若叔叔的右孩子是红的
                            Node t = uncle.right_child;
                            temp = connect34(false, uncle, parent, t, parent, temp, uncle.left_child, t.left_child, t.right_child);
                        }
                        temp.color = c;
                    } else if (parent.color == color.Red) {         //CASE 2 父节点是红色
                        uncle.color = color.Red;
                        parent.color = color.Black;
                    } else {                                       //叔叔黑色,父节点也是黑色,父节点所有孩子都是黑色
                        uncle.color = color.Red;
                        if (parent.parent != null)
                            Update_Tree_Remove(parent);
                    }
                } else {                    //叔叔是红色
                    parent.right_child = uncle.left_child;
                    parent.right_child.parent = parent;
                    uncle.left_child = parent;
                    uncle.parent = parent.parent;
                    if (parent.parent != null)
                        if (isLeftChild(parent))
                            parent.parent.left_child = uncle;
                        else
                            parent.parent.right_child = uncle;
                    parent.parent = uncle;
                    parent.color = color.Red;
                    uncle.color = color.Black;
                    Update_Tree_Remove(temp);
                }
            } else {   //反转情况
                uncle = parent.left_child;
                if (uncle.color == color.Black) {
                    if (uncle.left_child.color == color.Red || uncle.right_child.color == color.Red) {
                        color c = parent.color;
                        if (uncle.left_child.color == color.Red) {
                            Node t = uncle.left_child;
                            temp = connect34(false, uncle, t, parent, parent, t.left_child, t.right_child, uncle.right_child, temp);
                        } else {
                            Node t = uncle.right_child;
                            temp = connect34(false, t, uncle, parent, parent, uncle.left_child, t.left_child, t.right_child, temp);
                        }
                        temp.color = c;
                    } else if (parent.color == color.Red) {
                        uncle.color = color.Red;
                        parent.color = color.Black;
                    } else {
                        uncle.color = color.Red;
                        if (parent.parent != null)
                            Update_Tree_Remove(parent);
                    }
                } else {
                    parent.left_child = uncle.right_child;
                    parent.left_child.parent = parent;
                    uncle.right_child = parent;
                    uncle.parent = parent.parent;
                    if (parent.parent != null)
                        if (isLeftChild(parent))
                            parent.parent.left_child = uncle;
                        else
                            parent.parent.right_child = uncle;
                    parent.parent = uncle;
                    parent.color = color.Red;
                    uncle.color = color.Black;
                    Update_Tree_Remove(temp);
                }
            }
        }
    
        private boolean conflict(Node p) {
            return p.color == p.parent.color;
        }
    
        private void Recolor(Node p) {
            p.color = color.Red;
            p.left_child.color = color.Black;
            p.right_child.color = color.Black;
        }
    
        private Node connect34(boolean allblack, Node root, Node left, Node right, Node parent, Node child_1, Node child_2, Node
                child_3, Node child_4) {
            if (parent.parent != null) {
                if (isLeftChild(parent))
                    parent.parent.left_child = root;
                else
                    parent.parent.right_child = root;
                root.parent = parent.parent;
            } else
                root.parent = null;
            root.left_child = left;
            left.parent = root;
            root.right_child = right;
            right.parent = root;
            left.left_child = child_1;
            child_1.parent = left;
            left.right_child = child_2;
            child_2.parent = left;
            right.left_child = child_3;
            child_3.parent = right;
            right.right_child = child_4;
            child_4.parent = right;
            if (!allblack)
                Recolor(root);
            else {
                root.color = color.Black;
                root.left_child.color = color.Red;
                root.right_child.color = color.Red;
            }
            return root;
        }
    
    
        private boolean isRoot(Node temp) {
            return temp.parent == null;
        }
    
        private boolean isLeftChild(Node temp) {
            if (isRoot(temp))
                return true;
            return temp.parent.left_child == temp;
        }
    
        private void Update_Tree(Node temp) {
            boolean allblack;
            while (!isRoot(temp) && temp.parent.color == color.Red && temp.color == color.Red) {
                Node parent = temp.parent, grandparent = temp.parent.parent;
                if (parent == grandparent.left_child) {             //CASE 1
                    if (grandparent.right_child.color == color.Red) {
                        Recolor(grandparent);
                        temp = grandparent;
                    } else if (temp == parent.right_child)          //CASE 2
                    {
                        allblack = parent.left_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black;
                        temp = connect34(allblack, temp, parent, grandparent, grandparent, parent.left_child, temp.left_child, temp.right_child, grandparent.right_child);
                    } else {                                            //CASE 3
                        allblack = parent.right_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black;
                        temp = connect34(allblack, parent, temp, grandparent, grandparent, temp.left_child, temp.right_child, parent.right_child, grandparent.right_child);
                    }
                } else {                                            //Reverse situation
                    if (grandparent.left_child.color == color.Red) {
                        Recolor(grandparent);
                        temp = grandparent;
                    } else if (temp == parent.left_child) {
                        allblack = parent.right_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black;
                        temp = connect34(allblack, temp, grandparent, parent, grandparent, grandparent.left_child, temp.left_child, temp.right_child, parent.right_child);
                    } else {
                        allblack = parent.left_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black;
                        temp = connect34(allblack, parent, grandparent, temp, grandparent, grandparent.left_child, parent.left_child, temp.left_child, temp.right_child);
                    }
                }
            }
            if (isRoot(temp)) {
                root = temp;
                root.color = color.Black;
            }
        }
    
    
        public static void main(String args[]) {
            RBTree<Integer, Integer> RBT = new RBTree<>();
            ArrayList<Integer> z = new ArrayList<>();
            try {
                FileReader fw = new FileReader("/home/innovation/文档/num");
                BufferedReader br = new BufferedReader(fw);
                String x;
                while ((x = br.readLine()) != null)
                    z.add(Integer.parseInt(x));
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    //        while (z.size() < 10) {
    //            int x = (int) (Math.random() * 20);
    //            if (!z.contains(x))
    //                z.add(x);
    //        }
            for (int i = 0; i < z.size(); i++) {
    //            System.out.println(z.get(i));
                RBT.Insert(z.get(i), i);
            }
    //        RBT.LevelOrder();
            for (int i = 0; i < 20; i++) {
                System.out.println(z.get(i));
                if (z.get(i) == 8)
                    System.out.println(" ");
                RBT.Remove(z.get(i));
                RBT.LevelOrder();
            }
            System.out.println(" ");
        }
    }
  • 相关阅读:
    设计模式-迭代器模式(Iterator)
    设计模式-责任链模式(responsibility)
    设计模式-中介者模式(Mediator)
    设计模式-解释器模式(Interpreter)
    设计模式-适配器模式(Adapter)
    第十章——维护索引(8)——在计算列中创建索引提高性能
    第十章——维护索引(7)——使用索引视图提高性能
    第十章——维护索引(6)——查找无用索引
    第十章——维护索引(5)——查找丢失索引
    第十章——维护索引(4)——通过重组索引提高性能
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/9017492.html
Copyright © 2011-2022 走看看