广告
返回顶部
首页 > 资讯 > 后端开发 > Python >利用Java实现红黑树
  • 390
分享到

利用Java实现红黑树

2024-04-02 19:04:59 390人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1、红黑树的属性2、旋转3、插入4、删除5、所有代码6、演示1、红黑树的属性 红黑树是一种二分查找树,与普通的二分查找树不同的一点是,红黑树的每个节点都有一个颜色(color)属

1、红黑树的属性

红黑树是一种二分查找树,与普通的二分查找树不同的一点是,红黑树的每个节点都有一个颜色(color)属性。该属性的值要么是红色,要么是黑色。

通过限制从根到叶子的任何简单路径上的节点颜色,红黑树确保没有比任何其他路径长两倍的路径,从而使树近似平衡。

假设红黑树节点的属性有键(key)、颜色(color)、左子节点(left)、右子节点(right),父节点(parent)。

一棵红黑树必须满足下面有下面这些特性( 红黑树特性 ):

  • 树中的每个节点要么是红色,要么是黑色;
  • 根节点是黑色;
  • 每个叶子节点(null)是黑色;
  • 如果某节点是红色的,它的两个子节点都是黑色;
  • 对于每个节点到后面任一叶子节点(null)的所有路径,都有相同数量的黑色节点。

为了在红黑树代码中处理边界条件方便,我们用一个哨兵变量代替null。对于一个红黑树tree,哨兵变量RedBlackTree.NULL(下文代码中)是一个和其它节点有同样属性的节点,它的颜色(color)属性是黑色,其它属性可以任意取值。

我们使用哨兵变量是因为我们可以把一个节点node的子节点null当成一个普通节点。

在这里,我们使用哨兵变量RedBlackTree.NULL代替树中所有的null(所有的叶子节点及根节点的父节点)。

我们把从一个节点n(不包括)到任一叶子节点路径上的黑色节点的个数称为 黑色高度 ,用bh(n)表示。一棵红黑树的黑色高度是其根节点的黑色高度。

关于红黑树的搜索,求最小值,求最大值,求前驱,求后继这些操作的代码与二分查找树的这些操作的代码基本一致。可以在用java实现二分查找树查看。

结合上文给出下面的代码。

用一个枚举类Color表示颜色:


public enum Color {
    Black("黑色"), Red("红色");

    private String color;

    private Color(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return color;
    }
}

类Node表示节点:


public class Node {
    public int key;
    public Color color;
    public Node left;
    public Node right;
    public Node parent;

    public Node() {
    }

    public Node(Color color) {
        this.color = color;
    }

    public Node(int key) {
        this.key = key;
        this.color = Color.Red;
    }

    public int height() {
        return Math.max(left != RedBlackTree.NULL ? left.height() : 0, right != RedBlackTree.NULL ? right.height() : 0) + 1;
    }

    public Node minimum() {
        Node pointer = this;
        while (pointer.left != RedBlackTree.NULL)
            pointer = pointer.left;
        return pointer;
    }

    @Override
    public String toString() {
        String position = "null";
        if (this.parent != RedBlackTree.NULL)
            position = this.parent.left == this ? "left" : "right";
        return "[key: " + key + ", color: " + color + ", parent: " + parent.key + ", position: " + position + "]";
    }
}

类RedTreeNode表示红黑树:


public class RedBlackTree {

    // 表示哨兵变量
    public final static Node NULL = new Node(Color.Black);

    public Node root;

    public RedBlackTree() {
        this.root = NULL;
    }

}

2、旋转

红黑树的插入和删除操作,能改变红黑树的结构,可能会使它不再有前面所说的某些特性性。为了维持这些特性,我们需要改变树中某些节点的颜色和位置。

我们可以通过旋转改变节点的结构。主要有 左旋转 右旋转 两种方式。具体如下图所示。

左旋转:把一个节点n的右子节点right变为它的父节点,n变为right的左子节点,所以right不能为null。这时n的右指针空了出来,right的左子树被n挤掉,所以right原来的左子树称为n的右子树。

右旋转:把一个节点n的左子节点left变为它的父节点,n变为left的右子节点,所以left不能为null。这时n的左指针被空了出来,left的右子树被n挤掉,所以left原来的右子树被称为n的左子树。

可在RedTreeNode类中,加上如下实现代码:


public void leftRotate(Node node) {
        Node rightNode = node.right;

        node.right = rightNode.left;
        if (rightNode.left != RedBlackTree.NULL)
            rightNode.left.parent = node;

        rightNode.parent = node.parent;
        if (node.parent == RedBlackTree.NULL)
            this.root = rightNode;
        else if (node.parent.left == node)
            node.parent.left = rightNode;
        else
            node.parent.right = rightNode;

        rightNode.left = node;
        node.parent = rightNode;
    }

    public void rightRotate(Node node) {
        Node leftNode = node.left;

        node.left = leftNode.right;
        if (leftNode.right != RedBlackTree.NULL)
            leftNode.right.parent = node;

        leftNode.parent = node.parent;
        if (node.parent == RedBlackTree.NULL) {
            this.root = leftNode;
        } else if (node.parent.left == node) {
            node.parent.left = leftNode;
        } else {
            node.parent.right = leftNode;
        }

        leftNode.right = node;
        node.parent = leftNode;
    }

3、插入

红黑树的插入代码与二分查找树的插入代码非常相似。只不过红黑树的插入操作会改变红黑树的结构,使其不在有该有的特性。

在这里,新插入的节点默认是红色。

所以在插入节点之后,要有维护红黑树特性的代码。


public void insert(Node node) {
        Node parentPointer = RedBlackTree.NULL;
        Node pointer = this.root;

        while (this.root != RedBlackTree.NULL) {
            parentPointer = pointer;
            pointer = node.key < pointer.key ? pointer.left : pointer.right;
        }

        node.parent = parentPointer;
        if(parentPointer == RedBlackTree.NULL) {
            this.root = node;
        }else if(node.key < parentPointer.key) {
            parentPointer.left = node;
        }else {
            parentPointer.right = node;
        }

        node.left = RedBlackTree.NULL;
        node.right = RedBlackTree.NULL;
        node.color = Color.Red;
        // 维护红黑树属性的方法
        this.insertFixUp(node);
    }

用上述方法插入一个新节点的时候,有两类情况会违反红黑树的特性。

  • 当树中没有节点时,此时插入的节点称为根节点,而此节点的颜色为红色。
  • 当新插入的节点成为一个红色节点的子节点时,此时存在一个红色结点有红色子节点的情况。

对于第一类情况,可以直接把根结点设置为黑色;而针对第二类情况,需要根据具体条件,做出相应的解决方案。

具体代码如下:


public void insertFixUp(Node node) {
        // 当node不是根结点,且node的父节点颜色为红色
        while (node.parent.color == Color.Red) {
            // 先判断node的父节点是左子节点,还是右子节点,这不同的情况,解决方案也会不同
            if (node.parent == node.parent.parent.left) {
                Node uncleNode = node.parent.parent.right;
                if (uncleNode.color == Color.Red) {  // 如果叔叔节点是红色,则父父一定是黑色
                    // 通过把父父节点变成红色,父节点和兄弟节点变成黑色,然后在判断父父节点的颜色是否合适
                    uncleNode.color = Color.Black;
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    node = node.parent.parent;
                } else if (node == node.parent.right) {
                    node = node.parent;
                    this.leftRotate(node);
                } else {
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    this.rightRotate(node.parent.parent);
                }
            } else {
                Node uncleNode = node.parent.parent.left;
                if (uncleNode.color == Color.Red) {
                    uncleNode.color = Color.Black;
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    node = node.parent.parent;
                } else if (node == node.parent.left) {
                    node = node.parent;
                    this.rightRotate(node);
                } else {
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    this.leftRotate(node.parent.parent);
                }
            }
        }
        // 如果之前树中没有节点,那么新加入的点就成了新结点,而新插入的结点都是红色的,所以需要修改。
        this.root.color = Color.Black;
    }

下面的图分别对应第二类情况中的六种及相应处理结果。

情况1:

情况2:

情况3:

情况4:

情况5:

情况6:

4、删除

红黑树中节点的删除会使一个结点代替另外一个节点。所以先要实现这样的代码:


public void transplant(Node n1, Node n2) {
        if(n1.parent == RedBlackTree.NULL){
            this.root = n2;
        }else if(n1.parent.left == n1) {
            n1.parent.left = n2;
        }else {
            n1.parent.right = n2;
        }
        n2.parent = n1.parent;
    }


红黑树的删除节点代码是基于二分查找树的删除节点代码而写的。

删除结点代码:


public void delete(Node node) {
        Node pointer1 = node;
        // 用于记录被删除的颜色,如果是红色,可以不用管,但如果是黑色,可能会破坏红黑树的属性
        Color pointerOriginColor = pointer1.color;
        // 用于记录问题的出现点
        Node pointer2;
        if (node.left == RedBlackTree.NULL) {
            pointer2 = node.right;
            this.transplant(node, node.right);
        } else if (node.right == RedBlackTree.NULL) {
            pointer2 = node.left;
            this.transplant(node, node.left);
        } else {
            // 如要删除的字节有两个子节点,则找到其直接后继(右子树最小值),直接后继节点没有非空左子节点。
            pointer1 = node.right.minimum();
            // 记录直接后继的颜色和其右子节点
            pointerOriginColor = pointer1.color;
            pointer2 = pointer1.right;
            // 如果其直接后继是node的右子节点,不用进行处理
            if (pointer1.parent == node) {
                pointer2.parent = pointer1;
            } else {
                // 否则,先把直接后继从树中提取出来,用来替换node
                this.transplant(pointer1, pointer1.right);
                pointer1.right = node.right;
                pointer1.right.parent = pointer1;
            }
            // 用node的直接后继替换node,继承node的颜色
            this.transplant(node, pointer1);
            pointer1.left = node.left;
            pointer1.left.parent = pointer1;
            pointer1.color = node.color;
        }
        if (pointerOriginColor == Color.Black) {
            this.deleteFixUp(pointer2);
        }
    }

当被删除节点的颜色是黑色时需要调用方法维护红黑树的特性。

主要有两类情况:

  • 当node是红色时,直接变成黑色即可。
  • 当node是黑色时,需要调整红黑树结构。,

private void deleteFixUp(Node node) {
        // 如果node不是根节点,且是黑色
        while (node != this.root && node.color == Color.Black) {
            // 如果node是其父节点的左子节点
            if (node == node.parent.left) {
                // 记录node的兄弟节点
                Node pointer1 = node.parent.right;
                // 如果他兄弟节点是红色
                if (pointer1.color == Color.Red) {
                    pointer1.color = Color.Black;
                    node.parent.color = Color.Red;
                    leftRotate(node.parent);
                    pointer1 = node.parent.right;
                }
                if (pointer1.left.color == Color.Black && pointer1.right.color == Color.Black) {
                    pointer1.color = Color.Red;
                    node = node.parent;
                } else if (pointer1.right.color == Color.Black) {
                    pointer1.left.color = Color.Black;
                    pointer1.color = Color.Red;
                    rightRotate(pointer1);
                    pointer1 = node.parent.right;
                } else {
                    pointer1.color = node.parent.color;
                    node.parent.color = Color.Black;
                    pointer1.right.color = Color.Black;
                    leftRotate(node.parent);
                    node = this.root;
                }
            } else {
                // 记录node的兄弟节点
                Node pointer1 = node.parent.left;
                // 如果他兄弟节点是红色
                if (pointer1.color == Color.Red) {
                    pointer1.color = Color.Black;
                    node.parent.color = Color.Red;
                    rightRotate(node.parent);
                    pointer1 = node.parent.left;
                }
                if (pointer1.right.color == Color.Black && pointer1.left.color == Color.Black) {
                    pointer1.color = Color.Red;
                    node = node.parent;
                } else if (pointer1.left.color == Color.Black) {
                    pointer1.right.color = Color.Black;
                    pointer1.color = Color.Red;
                    leftRotate(pointer1);
                    pointer1 = node.parent.left;
                } else {
                    pointer1.color = node.parent.color;
                    node.parent.color = Color.Black;
                    pointer1.left.color = Color.Black;
                    rightRotate(node.parent);
                    node = this.root;
                }
            }

        }
        node.color = Color.Black;
    }

对第二类情况,有下面8种:

情况1:

情况2:

情况3:

情况4:

情况5:

情况6:

情况7:

情况8:

5、所有代码


public enum Color {
    Black("黑色"), Red("红色");

    private String color;

    private Color(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return color;
    }
}
public class Node {
    public int key;
    public Color color;
    public Node left;
    public Node right;
    public Node parent;

    public Node() {
    }

    public Node(Color color) {
        this.color = color;
    }

    public Node(int key) {
        this.key = key;
        this.color = Color.Red;
    }

    
    public int height() {
        return Math.max(left != RedBlackTree.NULL ? left.height() : 0, right != RedBlackTree.NULL ? right.height() : 0) + 1;
    }

    
    public Node minimum() {
        Node pointer = this;
        while (pointer.left != RedBlackTree.NULL)
            pointer = pointer.left;
        return pointer;
    }

    @Override
    public String toString() {
        String position = "null";
        if (this.parent != RedBlackTree.NULL)
            position = this.parent.left == this ? "left" : "right";
        return "[key: " + key + ", color: " + color + ", parent: " + parent.key + ", position: " + position + "]";
    }
}
import java.util.LinkedList;
import java.util.Queue;

public class RedBlackTree {

    public final static Node NULL = new Node(Color.Black);

    public Node root;

    public RedBlackTree() {
        this.root = NULL;
    }

    
    public void leftRotate(Node node) {
        Node rightNode = node.right;

        node.right = rightNode.left;
        if (rightNode.left != RedBlackTree.NULL)
            rightNode.left.parent = node;

        rightNode.parent = node.parent;
        if (node.parent == RedBlackTree.NULL)
            this.root = rightNode;
        else if (node.parent.left == node)
            node.parent.left = rightNode;
        else
            node.parent.right = rightNode;

        rightNode.left = node;
        node.parent = rightNode;
    }

    
    public void rightRotate(Node node) {
        Node leftNode = node.left;

        node.left = leftNode.right;
        if (leftNode.right != RedBlackTree.NULL)
            leftNode.right.parent = node;

        leftNode.parent = node.parent;
        if (node.parent == RedBlackTree.NULL) {
            this.root = leftNode;
        } else if (node.parent.left == node) {
            node.parent.left = leftNode;
        } else {
            node.parent.right = leftNode;
        }

        leftNode.right = node;
        node.parent = leftNode;
    }

    public void insert(Node node) {
        Node parentPointer = RedBlackTree.NULL;
        Node pointer = this.root;

        while (pointer != RedBlackTree.NULL) {
            parentPointer = pointer;
            pointer = node.key < pointer.key ? pointer.left : pointer.right;
        }

        node.parent = parentPointer;
        if (parentPointer == RedBlackTree.NULL) {
            this.root = node;
        } else if (node.key < parentPointer.key) {
            parentPointer.left = node;
        } else {
            parentPointer.right = node;
        }

        node.left = RedBlackTree.NULL;
        node.right = RedBlackTree.NULL;
        node.color = Color.Red;
        this.insertFixUp(node);
    }

    private void insertFixUp(Node node) {
        // 当node不是根结点,且node的父节点颜色为红色
        while (node.parent.color == Color.Red) {
            // 先判断node的父节点是左子节点,还是右子节点,这不同的情况,解决方案也会不同
            if (node.parent == node.parent.parent.left) {
                Node uncleNode = node.parent.parent.right;
                if (uncleNode.color == Color.Red) { // 如果叔叔节点是红色,则父父一定是黑色
                    // 通过把父父节点变成红色,父节点和兄弟节点变成黑色,然后在判断父父节点的颜色是否合适
                    uncleNode.color = Color.Black;
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    node = node.parent.parent;
                } else if (node == node.parent.right) { // node是其父节点的右子节点,且叔叔节点是黑色
                    // 对node的父节点进行左旋转
                    node = node.parent;
                    this.leftRotate(node);
                } else { // node如果叔叔节点是黑色,node是其父节点的左子节点,父父节点是黑色
                    // 把父节点变成黑色,父父节点变成红色,对父父节点进行右旋转
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    this.rightRotate(node.parent.parent);
                }
            } else {
                Node uncleNode = node.parent.parent.left;
                if (uncleNode.color == Color.Red) {
                    uncleNode.color = Color.Black;
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    node = node.parent.parent;
                } else if (node == node.parent.left) {
                    node = node.parent;
                    this.rightRotate(node);
                } else {
                    node.parent.color = Color.Black;
                    node.parent.parent.color = Color.Red;
                    this.leftRotate(node.parent.parent);
                }
            }
        }
        // 如果之前树中没有节点,那么新加入的点就成了新结点,而新插入的结点都是红色的,所以需要修改。
        this.root.color = Color.Black;
    }

    
    private void transplant(Node n1, Node n2) {

        if (n1.parent == RedBlackTree.NULL) { // 如果n1是根节点
            this.root = n2;
        } else if (n1.parent.left == n1) { // 如果n1是其父节点的左子节点
            n1.parent.left = n2;
        } else { // 如果n1是其父节点的右子节点
            n1.parent.right = n2;
        }
        n2.parent = n1.parent;
    }

    
    public void delete(Node node) {
        Node pointer1 = node;
        // 用于记录被删除的颜色,如果是红色,可以不用管,但如果是黑色,可能会破坏红黑树的属性
        Color pointerOriginColor = pointer1.color;
        // 用于记录问题的出现点
        Node pointer2;
        if (node.left == RedBlackTree.NULL) {
            pointer2 = node.right;
            this.transplant(node, node.right);
        } else if (node.right == RedBlackTree.NULL) {
            pointer2 = node.left;
            this.transplant(node, node.left);
        } else {
            // 如要删除的字节有两个子节点,则找到其直接后继(右子树最小值),直接后继节点没有非空左子节点。
            pointer1 = node.right.minimum();
            // 记录直接后继的颜色和其右子节点
            pointerOriginColor = pointer1.color;
            pointer2 = pointer1.right;
            // 如果其直接后继是node的右子节点,不用进行处理
            if (pointer1.parent == node) {
                pointer2.parent = pointer1;
            } else {
                // 否则,先把直接后继从树中提取出来,用来替换node
                this.transplant(pointer1, pointer1.right);
                pointer1.right = node.right;
                pointer1.right.parent = pointer1;
            }
            // 用node的直接后继替换node,继承node的颜色
            this.transplant(node, pointer1);
            pointer1.left = node.left;
            pointer1.left.parent = pointer1;
            pointer1.color = node.color;
        }
        if (pointerOriginColor == Color.Black) {
            this.deleteFixUp(pointer2);
        }
    }

    
    private void deleteFixUp(Node node) {
        // 如果node不是根节点,且是黑色
        while (node != this.root && node.color == Color.Black) {
            // 如果node是其父节点的左子节点
            if (node == node.parent.left) {
                // 记录node的兄弟节点
                Node pointer1 = node.parent.right;
                // 如果node兄弟节点是红色
                if (pointer1.color == Color.Red) {
                    pointer1.color = Color.Black;
                    node.parent.color = Color.Red;
                    leftRotate(node.parent);
                    pointer1 = node.parent.right;
                }
                if (pointer1.left.color == Color.Black && pointer1.right.color == Color.Black) {
                    pointer1.color = Color.Red;
                    node = node.parent;
                } else if (pointer1.right.color == Color.Black) {
                    pointer1.left.color = Color.Black;
                    pointer1.color = Color.Red;
                    rightRotate(pointer1);
                    pointer1 = node.parent.right;
                } else {
                    pointer1.color = node.parent.color;
                    node.parent.color = Color.Black;
                    pointer1.right.color = Color.Black;
                    leftRotate(node.parent);
                    node = this.root;
                }
            } else {
                // 记录node的兄弟节点
                Node pointer1 = node.parent.left;
                // 如果他兄弟节点是红色
                if (pointer1.color == Color.Red) {
                    pointer1.color = Color.Black;
                    node.parent.color = Color.Red;
                    rightRotate(node.parent);
                    pointer1 = node.parent.left;
                }
                if (pointer1.right.color == Color.Black && pointer1.left.color == Color.Black) {
                    pointer1.color = Color.Red;
                    node = node.parent;
                } else if (pointer1.left.color == Color.Black) {
                    pointer1.right.color = Color.Black;
                    pointer1.color = Color.Red;
                    leftRotate(pointer1);
                    pointer1 = node.parent.left;
                } else {
                    pointer1.color = node.parent.color;
                    node.parent.color = Color.Black;
                    pointer1.left.color = Color.Black;
                    rightRotate(node.parent);
                    node = this.root;
                }
            }

        }
        node.color = Color.Black;
    }

    private void innerWalk(Node node) {
        if (node != NULL) {
            innerWalk(node.left);
            System.out.println(node);
            innerWalk(node.right);
        }
    }

    
    public void innerWalk() {
        this.innerWalk(this.root);
    }

    
    public void print() {
        Queue<Node> queue = new LinkedList<>();
        queue.add(this.root);
        while (!queue.isEmpty()) {
            Node temp = queue.poll();
            System.out.println(temp);
            if (temp.left != NULL)
                queue.add(temp.left);
            if (temp.right != NULL)
                queue.add(temp.right);
        }
    }

    // 查找
    public Node search(int key) {
        Node pointer = this.root;
        while (pointer != NULL && pointer.key != key) {
            pointer = pointer.key < key ? pointer.right : pointer.left;
        }
        return pointer;
    }

}

6、演示

演示代码:


public class Test01 {
  public static void main(String[] args) {
    int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };
    RedBlackTree redBlackTree = new RedBlackTree();
    for (int i = 0; i < arr.length; i++) {
      redBlackTree.insert(new Node(arr[i]));
    }
    System.out.println("树的高度: " + redBlackTree.root.height());
    System.out.println("左子树的高度: " + redBlackTree.root.left.height());
    System.out.println("右子树的高度: " + redBlackTree.root.right.height());
    System.out.println("层次遍历");
    redBlackTree.print();
    // 要删除节点
    Node node = redBlackTree.search(4);
    redBlackTree.delete(node);
    System.out.println("树的高度: " + redBlackTree.root.height());
    System.out.println("左子树的高度: " + redBlackTree.root.left.height());
    System.out.println("右子树的高度: " + redBlackTree.root.right.height());
    System.out.println("层次遍历");
    redBlackTree.print();
  }
}

到此这篇关于利用Java实现红黑树的文章就介绍到这了,更多相关Java实现红黑树内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 利用Java实现红黑树

本文链接: https://www.lsjlt.com/news/135731.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 利用Java实现红黑树
    目录1、红黑树的属性2、旋转3、插入4、删除5、所有代码6、演示1、红黑树的属性 红黑树是一种二分查找树,与普通的二分查找树不同的一点是,红黑树的每个节点都有一个颜色(color)属...
    99+
    2022-11-12
  • java算法如何实现红黑树
    这篇文章主要介绍了java算法如何实现红黑树,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。红黑树定义红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计...
    99+
    2023-05-30
    java
  • java中treemap和treeset实现红黑树
    TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。TreeSet 和 TreeMap 的关系为了让大家了解 TreeMap 和 TreeSet 之间的关系,下面先看 TreeSe...
    99+
    2023-05-30
    java treemap treeset
  • HashMap红黑树入门(实现一个简单的红黑树)
    目录1.树结构入门1.1 什么是树?1.2 树结构常用术语1.3 二叉搜索树2.红黑树原理讲解2.1 红黑树的性质:2.2 红黑树案例分析3.手写红黑树4. HashMap底层的红黑...
    99+
    2022-11-12
  • java实现红黑树的代码怎么写
    本篇内容介绍了“java实现红黑树的代码怎么写”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 红黑树ja...
    99+
    2022-10-19
  • Java实现红黑树(平衡二叉树)的详细过程
    目录前言红黑二叉查找树2-3树2-3树的插入操作实现红黑二叉树结尾前言 在实现红黑树之前,我们先来了解一下符号表。 符号表的描述借鉴了Algorithms第四版,详情在:https...
    99+
    2022-11-12
  • C++实现红黑树应用实例代码
    红黑树的应用: 1、利用key_value对,快速查找,O(logn) socket与客户端id之间,形成映射关系(socket, id) 内存分配管理 ...
    99+
    2022-11-12
  • 关于Java的二叉树、红黑树、B+树详解
    目录1、二叉查找树2、平衡二叉查找树3、红黑树:4、 B树:5、 B+树6、红黑树 VS B+树数组和链表是常用的数据结构,数组虽然查找快(有序数组可以通过二分法查找),但是插入和删...
    99+
    2023-05-20
    Java二叉树 Java红黑树 JavaB+树
  • 红黑树的实现原理是什么
    本篇文章给大家分享的是有关红黑树的实现原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、摘要平衡二叉查找树是一个高度平衡的二叉树,也...
    99+
    2022-10-19
  • C++ RBTree红黑树的性质与实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树的插入五、代码实现一、红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Re...
    99+
    2023-03-08
    C++ RBTree红黑树 C++ RBTree C++ 红黑树
  • Java数据结构之红黑树的原理及实现
    目录为什么要有红黑树这种数据结构红黑树的简介红黑树的基本操作之旋转红黑树之添加元素红黑树之删除结点删除结点没有儿子的情况删除结点仅有一个儿子结点的情况删除结点有两个儿子结点红黑树动态...
    99+
    2022-11-13
  • C++数据结构之红黑树的实现
    目录一、什么是红黑树二、红黑树的约定三、红黑树vsAVL四、红黑树的实现1.找到插入的位置2.控制平衡3.测试代码五、完整代码1.test.c2.RBTree.h一、什么是红黑树 红...
    99+
    2022-11-13
    C++ 数据结构 红黑树 C++ 红黑树
  • C++详细实现红黑树流程详解
    目录红黑树的概念红黑树的性质红黑树的定义与树结构插入新增结点插入后维护红黑树性质的主逻辑旋转验证红黑树与AVl树的比较红黑树的应用红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点...
    99+
    2022-11-13
  • 为何Redis使用跳表而非红黑树实现SortedSet
    目录什么是跳表跳表的意义究竟在于何处?跳表的搜索时间复杂度跳表是不是很费内存?插入和删除的时间复杂度插入删除跳表索引动态更新跳表的代码实现(Java 版)数据结构定义搜索算法插入和删...
    99+
    2022-11-12
  • C语言实现红黑树详细步骤+代码
    目录红黑树的概念红黑树的性质红黑树的定义与树结构插入新增结点插入后维护红黑树性质的主逻辑拆解讨论:旋转验证红黑树与AVl树的比较红黑树的应用总结红黑树的概念 红黑树,是一种二叉搜索树...
    99+
    2022-11-12
  • C语言实现手写红黑树的示例代码
    目录前沿红黑树代码测试前沿 写C的红黑树前建议先看我博客这篇文章Java-红黑树 主要看原理 红黑树代码 #ifndef STUDY_RBTREE_H #define ...
    99+
    2022-11-13
  • Java红黑树的数据结构与算法解析
    目录红黑树的介绍红黑树的实现1.节点2.查找3.平衡化颜色反转 插入的实现红黑树的复杂度–总结红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的...
    99+
    2022-11-12
  • Java数据结构之红黑树的示例分析
    小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、红黑树所处数据结构的位置:在JDK源码中, 有treeMap...
    99+
    2023-05-30
    java
  • 基于红黑树插入操作原理及java实现的示例分析
    这篇文章主要介绍基于红黑树插入操作原理及java实现的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK。红黑树具有以下...
    99+
    2023-05-30
    java
  • C++ STL容器详解之红黑树部分模拟实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构 五、 红黑树的插入操作六、代码总结一、红黑树的概念 红黑树(Red Black Tree),是在计算机科学中用...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作