117.info
人生若只如初见

在C++中实现红黑树的基本结构

红黑树是一种自平衡的二叉搜索树,其基本结构可以通过以下代码实现:

#include 
using namespace std;

enum Color {RED, BLACK};

struct Node {
    int data;
    Color color;
    Node* left;
    Node* right;
    Node* parent;
    
    Node(int val) : data(val), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};

class RedBlackTree {
private:
    Node* root;
    
    void leftRotate(Node* x) {
        Node* 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* y) {
        Node* 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 fixViolation(Node* z) {
        while (z != root && z->parent->color == RED) {
            if (z->parent == z->parent->parent->left) {
                Node* y = z->parent->parent->right;
                if (y != nullptr && y->color == RED) {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                } else {
                    if (z == z->parent->right) {
                        z = z->parent;
                        leftRotate(z);
                    }
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    rightRotate(z->parent->parent);
                }
            } else {
                Node* y = z->parent->parent->left;
                if (y != nullptr && y->color == RED) {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                } else {
                    if (z == z->parent->left) {
                        z = z->parent;
                        rightRotate(z);
                    }
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    leftRotate(z->parent->parent);
                }
            }
        }
        root->color = BLACK;
    }

public:
    RedBlackTree() : root(nullptr) {}
    
    void insert(int val) {
        Node* z = new Node(val);
        Node* y = nullptr;
        Node* 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;
        }
        
        fixViolation(z);
    }
    
    // Traversal functions (inorder, preorder, postorder)
    // Other functions like delete, search, etc. can also be added
    
};

int main() {
    RedBlackTree rbTree;
    
    rbTree.insert(7);
    rbTree.insert(3);
    rbTree.insert(18);
    rbTree.insert(10);
    rbTree.insert(22);
    
    return 0;
}

在上面的代码中,我们定义了一个Node结构体表示红黑树的节点,其中包含数据值、颜色、左右孩子节点以及父节点。然后定义了一个RedBlackTree类来实现红黑树的基本操作,包括左旋转、右旋转、修正插入操作中可能出现的违反规则的情况等。

未经允许不得转载 » 本文链接:https://www.117.info/ask/feb23AzsIBgVfAFQ.html

推荐文章

  • c++闭包函数的用法是什么

    在C++中,使用lambda表达式可以创建闭包函数。闭包函数是一个可以捕获当前作用域内变量的函数对象,可以在函数内部引用外部变量。
    闭包函数的用法包括: 在...

  • c++闭包的作用有哪些

    C++中的闭包通常指lambda表达式,其主要作用包括: 封装局部变量:闭包可以捕获其所在作用域中的局部变量,使得这些变量可以在闭包内部被访问和修改,从而实现对...

  • c++中vector的常用方法有哪些

    push_back():在vector尾部添加一个元素
    pop_back():删除vector尾部的元素
    size():返回vector中元素的个数
    empty():判断vector是否为空
    ...

  • C#中的访问修饰符有哪些

    在C#中,主要有以下几种访问修饰符: public:表示成员是公共的,可以在任何地方进行访问。 private:表示成员是私有的,只能在定义该成员的类或结构体内部进行访...

  • 红黑树入门:理解C++中的自平衡机制

    红黑树是一种自平衡的二叉查找树,它的目的是保持树的高度近似平衡,以确保在最坏情况下的查找、插入和删除操作的时间复杂度为O(log n)。在C++中,STL的map和set...

  • 通过修改/etc/fstab在Ubuntu中设置延迟挂载、noatime选项等

    要在Ubuntu中设置延迟挂载和noatime选项,可以通过修改/etc/fstab文件来实现。
    首先,打开终端并输入以下命令以编辑/etc/fstab文件:
    sudo nano /etc/...

  • Ubuntu处理“磁盘已满”警告时的最佳实践

    当Ubuntu系统出现“磁盘已满”的警告时,以下是一些最佳实践: 清理临时文件:删除系统中的临时文件和缓存文件,可以通过运行sudo apt-get clean和sudo apt-get ...

  • Ubuntu挂载Git仓库作为本地目录

    要在Ubuntu上挂载Git仓库作为本地目录,可以使用以下步骤: 首先,确保你已经安装了Git和FUSE(Filesystem in Userspace)工具。如果没有安装,可以使用以下命令...