你真的了解红黑树的怎么实现的吗?

1.前言

红黑树是一种自平衡的二叉查找树,是在普通的二叉查找树的基础上增加了一些限制和规则,使得它能够自我调整来保持平衡。它的作用主要有以下几个方面:

  1. 查找和插入元素的时间复杂度都是O(logN),其中N为树中节点的个数,因此红黑树可以高效地进行查找和插入操作。

  2. 在很多需要动态维护有序序列数据结构的场景中,红黑树可以非常高效地实现这个目标。

  3. 红黑树还可以用于高效地实现区间查询等数据结构,比如线段树。在这种场景下,红黑树作为线段树的底层数据结构,能够提升线段树查询、更新的效率。

总之,红黑树是一种非常有用的数据结构,其自平衡特性使得它具有高效的查找和插入等操作,因此被广泛应用于数据处理和算法实现的领域。 

 2.原理分析

2.1.左旋操作

左旋是将当前节点往左旋转的操作。具体步骤如下:

  1. 将当前节点的右子节点(称为y)设为当前节点(称为x)的父节点。
  2. 将y的左子节点设为x的右子节点。
  3. 如果y的左子节点非空,将x设为y的左子节点的父节点。
  4. 将y的左子节点设为x。
  5. 将y的父节点设为原本x的父节点。
  6. 如果原本x的父节点为空,则将y设为红黑树的根节点;否则,如果x是其父节点的左子节点,则将y设为其父节点的左子节点;否则,将y设为其父节点的右子节点。

2.2右旋操作

左旋是将当前节点往左旋转的操作。具体步骤如下:

  1. 将当前节点的右子节点(称为y)设为当前节点(称为x)的父节点。
  2. 将y的左子节点设为x的右子节点。
  3. 如果y的左子节点非空,将x设为y的左子节点的父节点。
  4. 将y的左子节点设为x。
  5. 将y的父节点设为原本x的父节点。
  6. 如果原本x的父节点为空,则将y设为红黑树的根节点;否则,如果x是其父节点的左子节点,则将y设为其父节点的左子节点;否则,将y设为其父节点的右子节点。

左右旋的作用:

通过左旋和右旋操作可以改变节点之间的位置关系,从而保持红黑树的平衡性。这两个操作在插入或删除节点时经常被用到,以确保红黑树的性质得到维护和恢复。

2.3 插入节点

  1. 插入操作:

    • 首先根据传入的键值创建一个新节点,并将其颜色设置为红色。
    • 通过比较键值大小,将新节点插入到正确的位置上,确保满足二叉查找树的性质。
    • 调用修复插入操作来保证红黑树的性质:
      • 如果插入节点的父节点是黑色节点,那么不需要进行调整,红黑树的性质没有被破坏。
      • 如果插入节点的父节点是红色节点,那么可能会破坏红黑树的性质,需要进行相应的调整。

2.4插入后维持红黑树的平衡性

  1. 修复插入操作: 在红黑树中,有三种情况需要进行调整,分别是:插入节点的父节点是红色的情况下,叔节点是红色的情况下,和插入节点的父节点是红色且叔节点是黑色的情况下。调整的目标是使得插入节点的父节点是黑色,叔节点和祖父节点是红色,保持红黑树的性质。

    • 左旋转和右旋转:通过旋转操作来调整节点的位置,使得红黑树保持平衡。
    • 颜色翻转:通过改变节点的颜色来维护红黑树的性质。

2.5删除节点 

  1. 插入操作:

    • 首先根据传入的键值创建一个新节点,并将其颜色设置为红色。
    • 通过比较键值大小,将新节点插入到正确的位置上,确保满足二叉查找树的性质。
    • 调用修复插入操作来保证红黑树的性质:
      • 如果插入节点的父节点是黑色节点,那么不需要进行调整,红黑树的性质没有被破坏。
      • 如果插入节点的父节点是红色节点,那么可能会破坏红黑树的性质,需要进行相应的调整。

2.6删除后维持红黑树的平衡性

  1. 修复删除操作: 删除节点可能会破坏红黑树的性质,需要进行相应的调整。

    • 如果删除的节点是红色的,不会影响红黑树的性质,直接删除即可。
    • 如果删除的节点是黑色的,可能会导致红黑树的性质被破坏,需要进行相应的修复。修复的目标是保持每个节点到其后代叶节点的黑色节点数量相同。

3.代码实现

3.1准备工作

// 红黑树节点类
class RBNode {
    int data;
    RBNode parent;
    RBNode left;
    RBNode right;
    int color;

    public RBNode(int data) {
        this.data = data;
        this.parent = null;
        this.left = null;
        this.right = null;
        this.color = 1; // 默认节点为红色
    }
}
// 红黑树类
class RedBlackTree {
    private RBNode root;

    public RedBlackTree() {
        root = null;
    }
}

3.2.左旋操作

 // 左旋操作
    private void leftRotate(RBNode x) {
        RBNode y = x.right;
        x.right = y.left;
        if (y.left != null) {
            y.left.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            root = y;
        } else if (x == x.parent.left) {
            x.parent.left = y;
        } else {
            x.parent.right = y;
        }
        y.left = x;
        x.parent = y;
    }

3.3右旋操作

// 右旋操作
    private void rightRotate(RBNode y) {
        RBNode x = y.left;
        y.left = x.right;
        if (x.right != null) {
            x.right.parent = y;
        }
        x.parent = y.parent;
        if (y.parent == null) {
            root = x;
        } else if (y == y.parent.left) {
            y.parent.left = x;
        } else {
            y.parent.right = x;
        }
        x.right = y;
        y.parent = x;
    }

3.4插入节点

// 插入节点
    public void insert(int key) {
        RBNode newNode = new RBNode(key);
        RBNode current = root;
        RBNode parent = null;

        while (current != null) {
            parent = current;
            if (key < current.data) {
                current = current.left;
            } else {
                current = current.right;
            }
        }

        newNode.parent = parent;
        if (parent == null) {
            root = newNode;
        } else if (key < parent.data) {
            parent.left = newNode;
        } else {
            parent.right = newNode;
        }

        // 调整红黑树
        fixInsert(newNode);
    }

3.5插入后维持红黑树的平衡性

// 插入后修正红黑树平衡性
    private void fixInsert(RBNode node) {
        while (node.parent != null && node.parent.color == 1) {
            // 当前节点的父节点是祖父节点的左子节点
            if (node.parent == node.parent.parent.left) {
                RBNode uncle = node.parent.parent.right;
                // Case 1: 叔叔节点是红色
                if (uncle != null && uncle.color == 1) {
                    node.parent.color = 0;
                    uncle.color = 0;
                    node.parent.parent.color = 1;
                    node = node.parent.parent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是右子节点
                    if (node == node.parent.right) {
                        node = node.parent;
                        leftRotate(node);
                    }
                    // Case 3: 叔叔节点是黑色,且当前节点是左子节点
                    node.parent.color = 0;
                    node.parent.parent.color = 1;
                    rightRotate(node.parent.parent);
                }
            } else {
                // 当前节点的父节点是祖父节点的右子节点
                RBNode uncle = node.parent.parent.left;
                // Case 1: 叔叔节点是红色
                if (uncle != null && uncle.color == 1) {
                    node.parent.color = 0;
                    uncle.color = 0;
                    node.parent.parent.color = 1;
                    node = node.parent.parent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是左子节点
                    if (node == node.parent.left) {
                        node = node.parent;
                        rightRotate(node);
                    }
                    // Case 3: 叔叔节点是黑色,且当前节点是右子节点
                    node.parent.color = 0;
                    node.parent.parent.color = 1;
                    leftRotate(node.parent.parent);
                }
            }
        }
        root.color = 0;
    }

3.6删除节点

 // 删除节点
    public void delete(int key) {
        RBNode z = search(key);
        if (z == null) {
            return;
        }

        RBNode x, y;
        if (z.left == null || z.right == null) {
            y = z;
        } else {
            y = successor(z);
        }

        if (y.left != null) {
            x = y.left;
        } else {
            x = y.right;
        }

        if (x != null) {
            x.parent = y.parent;
        }

        if (y.parent == null) {
            root = x;
        } else if (y == y.parent.left) {
            y.parent.left = x;
        } else {
            y.parent.right = x;
        }

        if (y != z) {
            z.data = y.data;
        }

        if (y.color == 0) {
            fixDelete(x);
        }
    }

 

    // 查找节点
    public RBNode search(int key) {
        RBNode current = root;
        while (current != null && current.data != key) {
            if (key < current.data) {
                current = current.left;
            } else {
                current = current.right;
            }
        }
        return current;
    }

    // 查找后继节点
    private RBNode successor(RBNode x) {
        if (x.right != null) {
            RBNode current = x.right;
            while (current.left != null) {
                current = current.left;
            }
            return current;
        } else {
            RBNode y = x.parent;
            while (y != null && x == y.right) {
                x = y;
                y = y.parent;
            }
            return y;
        }
    }

3.7删除后维持红黑树的平衡性

  // 删除节点后修正红黑树平衡性
    private void fixDelete(RBNode node) {
        while (node != root && node.color == 0) {
            if (node == node.parent.left) {
                RBNode brother = node.parent.right;
                if (brother.color == 1) {
                    brother.color = 0;
                    node.parent.color = 1;
                    leftRotate(node.parent);
                    brother = node.parent.right;
                }
                if (brother.left.color == 0 && brother.right.color == 0) {
                    brother.color = 1;
                    node = node.parent;
                } else {
                    if (brother.right.color == 0) {
                        brother.left.color = 0;
                        brother.color = 1;
                        rightRotate(brother);
                        brother = node.parent.right;
                    }
                    brother.color = node.parent.color;
                    node.parent.color = 0;
                    brother.right.color = 0;
                    leftRotate(node.parent);
                    node = root;
                }
            } else {
                RBNode brother = node.parent.left;
                if (brother.color == 1) {
                    brother.color = 0;
                    node.parent.color = 1;
                    rightRotate(node.parent);
                    brother = node.parent.left;
                }
                if (brother.right.color == 0 && brother.left.color == 0) {
                    brother.color = 1;
                    node = node.parent;
                } else {
                    if (brother.left.color == 0) {
                        brother.right.color = 0;
                        brother.color = 1;
                        leftRotate(brother);
                        brother = node.parent.left;
                    }
                    brother.color = node.parent.color;
                    node.parent.color = 0;
                    brother.left.color = 0;
                    rightRotate(node.parent);
                    node = root;
                }
            }
        }
        node.color = 0;
    }

4.完整代码

// 红黑树节点类
class RBNode {
    int data;
    RBNode parent;
    RBNode left;
    RBNode right;
    int color;

    public RBNode(int data) {
        this.data = data;
        this.parent = null;
        this.left = null;
        this.right = null;
        this.color = 1; // 默认节点为红色
    }
}

// 红黑树类
class RedBlackTree {
    private RBNode root;

    public RedBlackTree() {
        root = null;
    }

    // 左旋操作
    private void leftRotate(RBNode x) {
        RBNode y = x.right;
        x.right = y.left;
        if (y.left != null) {
            y.left.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == null) {
            root = y;
        } else if (x == x.parent.left) {
            x.parent.left = y;
        } else {
            x.parent.right = y;
        }
        y.left = x;
        x.parent = y;
    }

    // 右旋操作
    private void rightRotate(RBNode y) {
        RBNode x = y.left;
        y.left = x.right;
        if (x.right != null) {
            x.right.parent = y;
        }
        x.parent = y.parent;
        if (y.parent == null) {
            root = x;
        } else if (y == y.parent.left) {
            y.parent.left = x;
        } else {
            y.parent.right = x;
        }
        x.right = y;
        y.parent = x;
    }

    // 插入节点
    public void insert(int key) {
        RBNode newNode = new RBNode(key);
        RBNode current = root;
        RBNode parent = null;

        while (current != null) {
            parent = current;
            if (key < current.data) {
                current = current.left;
            } else {
                current = current.right;
            }
        }

        newNode.parent = parent;
        if (parent == null) {
            root = newNode;
        } else if (key < parent.data) {
            parent.left = newNode;
        } else {
            parent.right = newNode;
        }

        // 调整红黑树
        fixInsert(newNode);
    }

    // 插入后修正红黑树平衡性
    private void fixInsert(RBNode node) {
        while (node.parent != null && node.parent.color == 1) {
            // 当前节点的父节点是祖父节点的左子节点
            if (node.parent == node.parent.parent.left) {
                RBNode uncle = node.parent.parent.right;
                // Case 1: 叔叔节点是红色
                if (uncle != null && uncle.color == 1) {
                    node.parent.color = 0;
                    uncle.color = 0;
                    node.parent.parent.color = 1;
                    node = node.parent.parent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是右子节点
                    if (node == node.parent.right) {
                        node = node.parent;
                        leftRotate(node);
                    }
                    // Case 3: 叔叔节点是黑色,且当前节点是左子节点
                    node.parent.color = 0;
                    node.parent.parent.color = 1;
                    rightRotate(node.parent.parent);
                }
            } else {
                // 当前节点的父节点是祖父节点的右子节点
                RBNode uncle = node.parent.parent.left;
                // Case 1: 叔叔节点是红色
                if (uncle != null && uncle.color == 1) {
                    node.parent.color = 0;
                    uncle.color = 0;
                    node.parent.parent.color = 1;
                    node = node.parent.parent;
                } else {
                    // Case 2: 叔叔节点是黑色,且当前节点是左子节点
                    if (node == node.parent.left) {
                        node = node.parent;
                        rightRotate(node);
                    }
                    // Case 3: 叔叔节点是黑色,且当前节点是右子节点
                    node.parent.color = 0;
                    node.parent.parent.color = 1;
                    leftRotate(node.parent.parent);
                }
            }
        }
        root.color = 0;
    }

    // 删除节点
    public void delete(int key) {
        RBNode z = search(key);
        if (z == null) {
            return;
        }

        RBNode x, y;
        if (z.left == null || z.right == null) {
            y = z;
        } else {
            y = successor(z);
        }

        if (y.left != null) {
            x = y.left;
        } else {
            x = y.right;
        }

        if (x != null) {
            x.parent = y.parent;
        }

        if (y.parent == null) {
            root = x;
        } else if (y == y.parent.left) {
            y.parent.left = x;
        } else {
            y.parent.right = x;
        }

        if (y != z) {
            z.data = y.data;
        }

        if (y.color == 0) {
            fixDelete(x);
        }
    }

    // 删除节点后修正红黑树平衡性
    private void fixDelete(RBNode node) {
        while (node != root && node.color == 0) {
            if (node == node.parent.left) {
                RBNode brother = node.parent.right;
                if (brother.color == 1) {
                    brother.color = 0;
                    node.parent.color = 1;
                    leftRotate(node.parent);
                    brother = node.parent.right;
                }
                if (brother.left.color == 0 && brother.right.color == 0) {
                    brother.color = 1;
                    node = node.parent;
                } else {
                    if (brother.right.color == 0) {
                        brother.left.color = 0;
                        brother.color = 1;
                        rightRotate(brother);
                        brother = node.parent.right;
                    }
                    brother.color = node.parent.color;
                    node.parent.color = 0;
                    brother.right.color = 0;
                    leftRotate(node.parent);
                    node = root;
                }
            } else {
                RBNode brother = node.parent.left;
                if (brother.color == 1) {
                    brother.color = 0;
                    node.parent.color = 1;
                    rightRotate(node.parent);
                    brother = node.parent.left;
                }
                if (brother.right.color == 0 && brother.left.color == 0) {
                    brother.color = 1;
                    node = node.parent;
                } else {
                    if (brother.left.color == 0) {
                        brother.right.color = 0;
                        brother.color = 1;
                        leftRotate(brother);
                        brother = node.parent.left;
                    }
                    brother.color = node.parent.color;
                    node.parent.color = 0;
                    brother.left.color = 0;
                    rightRotate(node.parent);
                    node = root;
                }
            }
        }
        node.color = 0;
    }

    // 查找节点
    public RBNode search(int key) {
        RBNode current = root;
        while (current != null && current.data != key) {
            if (key < current.data) {
                current = current.left;
            } else {
                current = current.right;
            }
        }
        return current;
    }

    // 查找后继节点
    private RBNode successor(RBNode x) {
        if (x.right != null) {
            RBNode current = x.right;
            while (current.left != null) {
                current = current.left;
            }
            return current;
        } else {
            RBNode y = x.parent;
            while (y != null && x == y.right) {
                x = y;
                y = y.parent;
            }
            return y;
        }
    }

    // 修改节点
    public void modify(int oldKey, int newKey) {
        RBNode node = search(oldKey);
        if (node != null) {
            delete(oldKey);
            insert(newKey);
        }
    }


    // 中序遍历红黑树
    private void inorderTraversal(RBNode node) {
        if (node != null) {
            inorderTraversal(node.left);
            System.out.print(node.data + " ");
            inorderTraversal(node.right);
        }
    }

    public void printTree() {
        inorderTraversal(root);
    }
}


public class Main {
    public static void main(String[] args) {
        RedBlackTree tree = new RedBlackTree();
        tree.insert(10);
        tree.insert(15);
        tree.insert(13);
        tree.insert(16);
        tree.insert(5);
        tree.insert(7);

        System.out.println("红黑树中序遍历结果:");
        tree.printTree();
    }
}

你可能感兴趣的:(java,开发语言,数据结构,算法,红黑树)