数据结构——红黑树

红黑树(Red-Black Tree)是一种自平衡的二叉查找树,它确保在插入和删除等基本操作后,树保持平衡,从而提供了快速的查找、插入和删除操作。红黑树之所以称为"红黑树",是因为每个节点都具有一个颜色属性,可以是红色或黑色,它们必须满足一些规则以保持树的平衡性。
性质:
1.树中的任何一个结点都带有颜色, 每个结点的颜色要么是红色, 要么是黑色
2.根结点是黑色
3.所有叶子结点是黑色(在红黑树中, 我们将底层叶结点看做有两个值为 NULL 的孩子结点, 以 NULL 结点作为红黑树的叶结点)
4.每个红色结点的孩子结点一定是黑色
5.对于树中的任意一个结点, 从该结点到所有叶结点的路径上一定包含相同数量的黑结点(我们将红黑树任意结点到叶子结点的路径上的黑色结点的个数称为该结点的 「黑高」)

根据性质得出:
1.没有一条路径比其他路径长出2倍
2.树的高度稳定趋近于log-n
3.一棵有n个节点的红黑树的高度,最多是两倍的2(log(n+1))

在这里插入图片描述
请添加图片描述

左旋操作(Left Rotation)
左旋是一种将节点向左移动的操作,通常用于修复红黑树的性质。左旋的基本思想是将一个节点的右子节点提升为新的父节点,同时原来的父节点成为新的左子节点。这可以保持二叉搜索树的性质,并且确保红黑树的平衡。

右旋操作(Right Rotation)
右旋是一种将节点向右移动的操作,也用于修复红黑树的性质。右旋的基本思想是将一个节点的左子节点提升为新的父节点,同时原来的父节点成为新的右子节点。这同样可以保持二叉搜索树的性质,并确保红黑树的平衡。

#include <iostream>

enum class Color { RED, BLACK };

template <typename T>
struct Node {
    T data;
    Node* parent;
    Node* left;
    Node* right;
    Color color;
};

template <typename T>
class RedBlackTree {
private:
    Node<T>* root;

    // 左旋转
    void leftRotate(Node<T>* x) {
        Node<T>* y = x->right;
        x->right = y->left;
        if (y->left != nullptr) {
            y->left->parent = x;
        }
        y->parent = x->parent;
        if (x->parent == nullptr) {
            root = y;
        } else if (x == x->parent->left) {
            x->parent->left = y;
        } else {
            x->parent->right = y;
        }
        y->left = x;
        x->parent = y;
    }

    // 右旋转
    void rightRotate(Node<T>* y) {
        Node<T>* x = y->left;
        y->left = x->right;
        if (x->right != nullptr) {
            x->right->parent = y;
        }
        x->parent = y->parent;
        if (y->parent == nullptr) {
            root = x;
        } else if (y == y->parent->left) {
            y->parent->left = x;
        } else {
            y->parent->right = x;
        }
        x->right = y;
        y->parent = x;
    }

    // 插入节点修正
    void insertFixup(Node<T>* z) {
        while (z->parent != nullptr && z->parent->color == Color::RED) {
            if (z->parent == z->parent->parent->left) {
                Node<T>* y = z->parent->parent->right;
                if (y != nullptr && y->color == Color::RED) {
                    z->parent->color = Color::BLACK;
                    y->color = Color::BLACK;
                    z->parent->parent->color = Color::RED;
                    z = z->parent->parent;
                } else {
                    if (z == z->parent->right) {
                        z = z->parent;
                        leftRotate(z);
                    }
                    z->parent->color = Color::BLACK;
                    z->parent->parent->color = Color::RED;
                    rightRotate(z->parent->parent);
                }
            } else {
                Node<T>* y = z->parent->parent->left;
                if (y != nullptr && y->color == Color::RED) {
                    z->parent->color = Color::BLACK;
                    y->color = Color::BLACK;
                    z->parent->parent->color = Color::RED;
                    z = z->parent->parent;
                } else {
                    if (z == z->parent->left) {
                        z = z->parent;
                        rightRotate(z);
                    }
                    z->parent->color = Color::BLACK;
                    z->parent->parent->color = Color::RED;
                    leftRotate(z->parent->parent);
                }
            }
        }
        root->color = Color::BLACK;
    }

    // 插入节点
    void insert(Node<T>* z) {
        Node<T>* y = nullptr;
        Node<T>* x = root;
        while (x != nullptr) {
            y = x;
            if (z->data < x->data) {
                x = x->left;
            } else {
                x = x->right;
            }
        }
        z->parent = y;
        if (y == nullptr) {
            root = z;
        } else if (z->data < y->data) {
            y->left = z;
        } else {
            y->right = z;
        }
        z->left = nullptr;
        z->right = nullptr;
        z->color = Color::RED;
        insertFixup(z);
    }

    // 中序遍历
    void inorder(Node<T>* x) {
        if (x != nullptr) {
            inorder(x->left);
            std::cout << x->data << " ";
            inorder(x->right);
        }
    }

public:
    RedBlackTree() : root(nullptr) {}

    // 插入
    void insert(T data) {
        Node<T>* z = new Node<T>;
        z->data = data;
        z->left = nullptr;
        z->right = nullptr;
        z->color = Color::RED;
        insert(z);
    }

    // 中序遍历
    void inorder() {
        inorder(root);
    }
};

int main() {
    RedBlackTree<int> rbTree;
    rbTree.insert(10);
    rbTree.insert(20);
    rbTree.insert(30);
    rbTree.insert(40);
    rbTree.insert(50);
    rbTree.insert(60);
    rbTree.insert(70);

    std::cout << "Inorder Traversal of Red-Black Tree: ";
    rbTree.inorder();
    std::cout << std::endl;

    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
红黑树是一种自平衡的二叉查找树,它在插入和删除节点时能够保持树的平衡。红黑树的概念可以参考。在Java中实现红黑树,可以按照以下步骤进行: 1. 首先将红黑树当作一颗二叉查找树,将新节点插入到适当的位置上。 2. 将插入的节点着色为"红色"。 3. 根据红黑树的特性,通过一系列的旋转和着色等操作,使树重新保持红黑树的性质。 具体的插入过程可以参考中提供的代码。在代码中,使用了左旋转、右旋转和颜色翻转等操作来重新平衡红黑树。 首先,如果节点的右子树是红色而左子树是黑色,可以通过左旋转操作将其变为左子树为红色,右子树为黑色的情况。 其次,如果节点的左子树和左子树的左子树都是红色,可以通过右旋转操作将其修正为上述情况。 最后,如果节点的左子树和右子树都是红色,可以通过颜色翻转操作将其修正为左子树和右子树都为黑色的情况。 在插入完节点后,需要将根节点的颜色设置为黑色,以确保红黑树的性质满足。 这样,通过以上的步骤,就能够实现对红黑树的插入操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java数据结构红黑树的真正理解](https://download.csdn.net/download/weixin_38622475/12770272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Java高阶数据结构红黑树](https://blog.csdn.net/qq15035899256/article/details/126678970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java数据结构——红黑树](https://blog.csdn.net/weixin_30699463/article/details/95256212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值