手写红黑树添加元素以及遍历操作(RBT)

代码放在文末
红黑树添加元素:保持根为黑色,左旋。
需要左旋的情况如下图所示:
在这里插入图片描述

如果先添加40,再添加30,则为左旋,无需操作。
如过先添加30,再添加40,需要左旋操作,保证红黑树为左旋红黑树。

下图为左旋和颜色变换的示意图(包括变换的代码)
在这里插入图片描述红黑树添加元素:颜色反转。
先在40的左侧和右侧分别贴上30和50(节点默认颜色为红色,根节点默认黑色)。
由于红黑树本质上就是二三树,一个四节点转换为3个2节点
首先三个节点在红黑树中都为单独的黑色节点,同时又需要保证层数不变,因此根节点变为红色,而两个子节点为黑色。在这里插入图片描述需要右旋的情况如下图所示:
在这里插入图片描述

// An highlighted block
import javax.swing.*;
        import javax.xml.soap.Node;
        import java.util.LinkedList;
        import java.util.Queue;

/**
 * @author xxo
 * @param <E>
 */
public class RBT<E extends Comparable<E>> {
    //因为添加元素时要比较大小,所以使用了Comparable
    private static final boolean RED = true;
    private static final boolean BLACK = false;

    public Node root;    //根节点
    private int size;    //总共的数量
    public int size() { return size; }

    //添加节点,递归
    public void addEle(E e){
        root = addEle(root,e);//以该节点为根,添加红黑树的元素
        root.color = BLACK; //始终保持新添加到的子树的根是黑色。
    }

    /**
     * 将元素E添加到node为根的那个树上并且将新树的根返回
     * @param node
     * @param e
     * @return
     *
     */

    private Node addEle(Node node,E e){   //添加元素e到以node为根的子树上
        if (node == null){                //并且返回新的根节点
            size++;
            return new Node(e);
        }

        if (e.compareTo(node.e)<0){
            node.left = addEle(node.left,e);    //与根节点比较,比根节点小往左加,大往有加
        }else{
            node.right = addEle(node.right,e);
        }

        //左旋
        if(isRed(node.right)&&!isRed(node.left)){
            node = leftRotate(node);
        }


        //右旋
        if (isRed(node.left)&&isRed(node.left.left)){
            node = rightRoatate(node);
        }


        //颜色翻转
        if (isRed(node.left)&&isRed(node.right)){
            flipColors(node);
        }

        return node;
    }

    //        node                             x
    //       /    \         左旋             /    \
    //     T1      x     ---------->      node    T3
    //           /   \                   /   \
    //          T2   T3                T1     T2
    private Node leftRotate(Node node) {
        Node x = node.right;
        node.right = x.left;
        x.left = node;

        x.color = node.color;
        node.color = RED;

        return x;
    }
    //颜色翻转
    private void flipColors(Node node){
        node.color = RED;
        node.left.color = BLACK;
        node.right.color = BLACK;
    }



    //        node                             x
    //       /    \         右旋             /    \
    //     x      T2     ---------->       y      node
    //    / \                                    /   \
    //   y   T1                                T1     T2
    private Node rightRoatate(Node node){
        Node x = node.left;
        node.left = x.right;
        x.right = node;

        x.color = node.color;
        node.color = RED;

        return x;
    }

    private boolean isRed(Node node){
        if(node==null)return BLACK;
        return node.color;
    }

    private class Node{
        public E e;
        public Node left;
        public Node right;
        public boolean color;

        public Node(E e){
            this.e = e;
            this.left = null;
            this.right = null;
            this.color = RED;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "e=" + e +
                    ", color=" + color +
                    '}';
        }
    }
    /**
     * 层次遍历树
     */
    public void levelOrder(){
        if(root==null){
            return;
        }
        Queue<Node> queue = new LinkedList();
        queue.add(root);
        while(!queue.isEmpty()){
            Node curNode = queue.remove();
            System.out.println(curNode);
            if (curNode.left!=null){
                queue.add(curNode.left);
            }
            if (curNode.right!=null){
                queue.add(curNode.right);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值