红黑树的性质及代码实现

1.  2-3树

        性质:1.结点可以存放一个元素或者两个元素,所以,每个结点有2个或3个孩子

                2.  2-3是一颗绝对平衡的树

        图示:

红黑树与2-3树的等价性:

        

 

2.什么是红黑树

         红黑树是一种自平衡二叉查找树,实在计算机科学中用到的一种数据结构,其用途是实现关联数组。

        红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它可以在O(log n)时间内做查找,插入和删除

3.红黑树的基本性质

        1.每个结点或者是红色的,或者时黑色的

        2.根节点时黑色的

        3.每一个叶子结点(最后的空结点)是黑色的

        4.如果一个结点时红色的,那么他的孩子结点都是黑色的

        5.从任意一个结点到叶子结点,经过的黑色结点是一样的

4.红黑树的代码实现

        1.构建树

    private class Node {
        // 结点内容
        T val;
        //  左右孩子
        Node left;
        Node right;

        Boolean isRed; // 记录结点的颜色

        public Node(T val) {
            this.val = val;
            this.isRed = true;
            this.left = null;
            this.right = null;
        }
    }

    Node root;//根节点
    int size; //  树中结点的个数

    public RBTree() {
        this.root = null;
        this.size = 0;
    }

         2.获取树中结点的个数

    // 获取树中结点的个数
    public int getSize() {
        return this.size;
    }

        3.判断是否为空树

    // 判断是否为空树
    public boolean isEmpty() {
        return this.root == null;
    }

        4.辅助方法:获取结点的颜色

    // 辅助的方法: 获取结点的颜色
    public boolean getColor(Node node) {
        if (node == null) {
            return false;
        }
        return node.isRed;
    }

        5.向树中添加结点

    // 在以node为根的二分搜索树中添加val
    private Node add(Node node, T val) {
        // 1、递归终止的条件
        if (node == null) {
            this.size++;
            return new Node(val);
        }
        // 2、递归操作
        if (node.val.compareTo(val) > 0) {
            node.left = add(node.left, val);
        } else {
            node.right = add(node.right, val);
        }

        // 以node结点为根的树不平衡,就要调整
        Node resultNode = node;
        // 左旋转
        if (!getColor(resultNode.left) && getColor(resultNode.right)) {
            resultNode = leftRotate(resultNode);
        }

        // 右旋转
        if (getColor(resultNode.left) && getColor(resultNode.left.left)) {
            resultNode = rightRotate(resultNode);
        }

        //颜色反转
        if (getColor(resultNode.left) && getColor(resultNode.right)) {
            flipColor(resultNode);
        }


        return resultNode;
    }

        6.查询val是否存在于树中

 public Node find(T val) {
        return find(root, val);
    }

    private Node find(Node node, T val) {
        // 1、递归终止条件
        if (node == null) {
            return null;
        }
        // 2、 递归操作
        if (node.val.compareTo(val) == 0) {
            return node;
        } else if (node.val.compareTo(val) < 0) {
            return find(node.right, val);
        } else {
            return find(node.left, val);
        }
    }

        7.层序遍历,并获取各结点的颜色

    // 层序遍历,并获取个结点的颜色
    public void levelTraverse() {
        LinkedList<Node> queue = new LinkedList<>();
        if (this.root == null) {
            return;
        }
        queue.add(this.root);
        while (!queue.isEmpty()) {
            Node node = queue.poll();
            System.out.println(node.val + "<---->" + (getColor(node)?"RED":"BLACK"));
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
        }
    }

        8.方法补充(左旋转,右旋转,颜色反转)

    /**
     * 右旋转
     */

    private Node rightRotate(Node node) {
        Node x = node.left;
        // 1、保存x的右子树
        Node t2 = x.right;
        // 2、将node作为x的右子树
        x.right = node;
        // 3、将t3作为y的左子树
        node.left = t2;
        // 更新颜色
        x.isRed = node.isRed;
        node.isRed = true;
        return x;
    }

    /**
     * 左旋转
     */
    private Node leftRotate(Node node) {
        Node x = node.right;
        // 1、保存x的左孩子
        Node t2 = x.left;
        // 2、将node作为x的左树
        x.left = node;
        // 3、将t2作为node的右树
        node.right = t2;
        // 更新颜色
        x.isRed = node.isRed;
        node.isRed = true;
        return x;
    }


    // 颜色反转
    private void flipColor(Node node) {
        node.isRed = true;
        node.left.isRed = false;
        node.right.isRed = false;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值