数据结构之树(红黑树)

2-3树的定义

在这里插入图片描述
在这里插入图片描述

2-3树保持平衡

插入3-节点:
在这里插入图片描述插入3-节点,父节点为2-节点:
在这里插入图片描述插入3-节点,父节点为3-节点:
在这里插入图片描述

红黑树和2-3树

在这里插入图片描述
3节点的左节点是红节点。

在这里插入图片描述

添加元素的操作

节点默认为红色

private class Node{
    public K key;
    public V value;
    public Node left, right;
    public boolean color;

    public Node(K key, V value){
        this.key = key;
        this.value = value;
        left = null;
        right = null;
        color = RED;
    }
}

使根节点为黑色

public void add(K key, V value){
    root = add(root, key, value);
    root.color = BLACK; // 最终根节点为黑色节点
}

左旋转

在这里插入图片描述元素添加到右边,不满足红黑树的定义,红色节点应该在左边。

//   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;
}

颜色翻转

在这里插入图片描述1.添加42,为根节点,默认为黑节点
2.添加37,为红节点,依然为红黑树
3.再添加66,为红节点,则不是红黑树
4.要满足红黑树的性质,则进行颜色翻转,3个节点都为黑节点
5.根节点需要和父节点融合,则变为红节点

在这里插入图片描述

// 颜色翻转
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 rightRotate(Node node){

    Node x = node.left;

    // 右旋转
    node.left = x.right;
    x.right = node;

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

    return x;
}

添加一个新元素

在这里插入图片描述

// 向二分搜索树中添加新的元素(key, value)
public void add(K key, V value){
    root = add(root, key, value);
    root.color = BLACK; // 最终根节点为黑色节点
}


// 向以node为根的二分搜索树中插入元素(key, value),递归算法
// 返回插入新节点后二分搜索树的根
private Node add(Node node, K key, V value){

    if(node == null){
        size ++;
        return new Node(key, value); // 默认插入红色节点
    }

    if(key.compareTo(node.key) < 0)
        node.left = add(node.left, key, value);
    else if(key.compareTo(node.key) > 0)
        node.right = add(node.right, key, value);
    else // key.compareTo(node.key) == 0
        node.value = value;

    if (isRed(node.right) && !isRed(node.left))
        node = leftRotate(node);

    if (isRed(node.left) && isRed(node.left.left))
        node = rightRotate(node);

    if (isRed(node.left) && isRed(node.right))
        flipColors(node);

    return node;
}

// 判断节点node的颜色
private boolean isRed(Node node){
    if(node == null)
        return BLACK;
    return node.color;
}

总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值