红黑树实现

Posted INnoVation-V2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树实现相关的知识,希望对你有一定的参考价值。

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(" ");
    }
}

 

以上是关于红黑树实现的主要内容,如果未能解决你的问题,请参考以下文章

红黑树底层实现原理分析及JAVA代码实现

STL详解—— 用一棵红黑树同时封装出map和set

map和set的模拟实现

浅谈红黑树(C语言代码实现)

红黑树来实现map&set

红黑树插入与删除完整代码(dart语言实现)