找回密码
 中文实名注册
搜索
查看: 256|回复: 0

红黑树

[复制链接]

731

主题

577

回帖

2万

积分

管理员

积分
24978
发表于 2025-8-20 13:30:34 | 显示全部楼层 |阅读模式
[C++] 纯文本查看 复制代码
#include <iostream>
#include <algorithm>
using namespace std;

// 定义节点颜色
enum Color { RED, BLACK };

// 红黑树节点结构
template <typename T>
struct Node {
    T data;
    Color color;
    Node *left, *right, *parent;
    
    // 构造函数
    Node(T val) : data(val), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};

// 红黑树类
template <typename T>
class RedBlackTree {
private:
    Node<T>* root;
    Node<T>* NIL;  // 哨兵节点,代表空节点
    
    // 左旋转操作
    void leftRotate(Node<T>* x) {
        Node<T>* y = x->right;
        x->right = y->left;
        
        if (y->left != NIL)
            y->left->parent = x;
        
        y->parent = x->parent;
        
        if (x->parent == NIL)
            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 != NIL)
            x->right->parent = y;
        
        x->parent = y->parent;
        
        if (y->parent == NIL)
            root = x;
        else if (y == y->parent->right)
            y->parent->right = x;
        else
            y->parent->left = x;
        
        x->right = y;
        y->parent = x;
    }
    
    // 插入后修复红黑树性质
    void insertFixup(Node<T>* z) {
        while (z->parent->color == RED) {
            if (z->parent == z->parent->parent->left) {
                Node<T>* y = z->parent->parent->right;  // 叔叔节点
                
                // 情况1:叔叔是红色
                if (y->color == RED) {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                } 
                // 情况2:叔叔是黑色,且z是右孩子
                else {
                    if (z == z->parent->right) {
                        z = z->parent;
                        leftRotate(z);
                    }
                    // 情况3:叔叔是黑色,且z是左孩子
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    rightRotate(z->parent->parent);
                }
            } 
            // 镜像情况:父节点是祖父节点的右孩子
            else {
                Node<T>* y = z->parent->parent->left;  // 叔叔节点
                
                // 情况1:叔叔是红色
                if (y->color == RED) {
                    z->parent->color = BLACK;
                    y->color = BLACK;
                    z->parent->parent->color = RED;
                    z = z->parent->parent;
                } 
                // 情况2:叔叔是黑色,且z是左孩子
                else {
                    if (z == z->parent->left) {
                        z = z->parent;
                        rightRotate(z);
                    }
                    // 情况3:叔叔是黑色,且z是右孩子
                    z->parent->color = BLACK;
                    z->parent->parent->color = RED;
                    leftRotate(z->parent->parent);
                }
            }
            
            if (z == root)
                break;
        }
        root->color = BLACK;  // 确保根节点是黑色
    }
    
    //  Transplant操作:用v子树替换u子树
    void transplant(Node<T>* u, Node<T>* v) {
        if (u->parent == NIL)
            root = v;
        else if (u == u->parent->left)
            u->parent->left = v;
        else
            u->parent->right = v;
        v->parent = u->parent;
    }
    
    // 查找最小节点
    Node<T>* minimum(Node<T>* node) {
        while (node->left != NIL)
            node = node->left;
        return node;
    }
    
    // 删除后修复红黑树性质
    void deleteFixup(Node<T>* x) {
        while (x != root && x->color == BLACK) {
            if (x == x->parent->left) {
                Node<T>* w = x->parent->right;  // 兄弟节点
                
                // 情况1:兄弟是红色
                if (w->color == RED) {
                    w->color = BLACK;
                    x->parent->color = RED;
                    leftRotate(x->parent);
                    w = x->parent->right;
                }
                
                // 情况2:兄弟的两个孩子都是黑色
                if (w->left->color == BLACK && w->right->color == BLACK) {
                    w->color = RED;
                    x = x->parent;
                } 
                else {
                    // 情况3:兄弟的左孩子是红色,右孩子是黑色
                    if (w->right->color == BLACK) {
                        w->left->color = BLACK;
                        w->color = RED;
                        rightRotate(w);
                        w = x->parent->right;
                    }
                    
                    // 情况4:兄弟的右孩子是红色
                    w->color = x->parent->color;
                    x->parent->color = BLACK;
                    w->right->color = BLACK;
                    leftRotate(x->parent);
                    x = root;
                }
            } 
            // 镜像情况:x是其父节点的右孩子
            else {
                Node<T>* w = x->parent->left;  // 兄弟节点
                
                // 情况1:兄弟是红色
                if (w->color == RED) {
                    w->color = BLACK;
                    x->parent->color = RED;
                    rightRotate(x->parent);
                    w = x->parent->left;
                }
                
                // 情况2:兄弟的两个孩子都是黑色
                if (w->right->color == BLACK && w->left->color == BLACK) {
                    w->color = RED;
                    x = x->parent;
                } 
                else {
                    // 情况3:兄弟的右孩子是红色,左孩子是黑色
                    if (w->left->color == BLACK) {
                        w->right->color = BLACK;
                        w->color = RED;
                        leftRotate(w);
                        w = x->parent->left;
                    }
                    
                    // 情况4:兄弟的左孩子是红色
                    w->color = x->parent->color;
                    x->parent->color = BLACK;
                    w->left->color = BLACK;
                    rightRotate(x->parent);
                    x = root;
                }
            }
        }
        x->color = BLACK;
    }
    
    // 递归删除树
    void destroyTree(Node<T>* node) {
        if (node != NIL) {
            destroyTree(node->left);
            destroyTree(node->right);
            delete node;
        }
    }
    
    // 前序遍历辅助函数
    void preOrderHelper(Node<T>* node) {
        if (node != NIL) {
            cout << node->data << "(" << (node->color == RED ? "红" : "黑") << ") ";
            preOrderHelper(node->left);
            preOrderHelper(node->right);
        }
    }
    
    // 中序遍历辅助函数
    void inOrderHelper(Node<T>* node) {
        if (node != NIL) {
            inOrderHelper(node->left);
            cout << node->data << "(" << (node->color == RED ? "红" : "黑") << ") ";
            inOrderHelper(node->right);
        }
    }
    
    // 后序遍历辅助函数
    void postOrderHelper(Node<T>* node) {
        if (node != NIL) {
            postOrderHelper(node->left);
            postOrderHelper(node->right);
            cout << node->data << "(" << (node->color == RED ? "红" : "黑") << ") ";
        }
    }
    
    // 查找辅助函数
    Node<T>* searchHelper(Node<T>* node, T val) {
        if (node == NIL || val == node->data)
            return node;
        
        if (val < node->data)
            return searchHelper(node->left, val);
        else
            return searchHelper(node->right, val);
    }

public:
    // 构造函数
    RedBlackTree() {
        NIL = new Node<T>(0);
        NIL->color = BLACK;
        NIL->left = NIL->right = NIL->parent = NIL;
        root = NIL;
    }
    
    // 析构函数
    ~RedBlackTree() {
        destroyTree(root);
        delete NIL;
    }
    
    // 插入节点
    void insert(T val) {
        Node<T>* z = new Node<T>(val);
        z->left = NIL;
        z->right = NIL;
        
        Node<T>* y = NIL;
        Node<T>* x = root;
        
        // 找到插入位置
        while (x != NIL) {
            y = x;
            if (z->data < x->data)
                x = x->left;
            else
                x = x->right;
        }
        
        z->parent = y;
        
        if (y == NIL)
            root = z;
        else if (z->data < y->data)
            y->left = z;
        else
            y->right = z;
        
        // 新节点初始颜色为红色
        z->color = RED;
        
        // 修复红黑树性质
        insertFixup(z);
    }
    
    // 删除节点
    void remove(T val) {
        Node<T>* z = searchHelper(root, val);
        if (z == NIL) {
            cout << "值 " << val << " 不在树中,无法删除" << endl;
            return;
        }
        
        Node<T>* y = z;
        Node<T>* x;
        Color yOriginalColor = y->color;
        
        // 只有右子树或没有子树
        if (z->left == NIL) {
            x = z->right;
            transplant(z, z->right);
        }
        // 只有左子树
        else if (z->right == NIL) {
            x = z->left;
            transplant(z, z->left);
        }
        // 有两个子树
        else {
            y = minimum(z->right);
            yOriginalColor = y->color;
            x = y->right;
            
            if (y->parent == z)
                x->parent = y;
            else {
                transplant(y, y->right);
                y->right = z->right;
                y->right->parent = y;
            }
            
            transplant(z, y);
            y->left = z->left;
            y->left->parent = y;
            y->color = z->color;
        }
        
        delete z;
        
        // 如果删除的是黑色节点,需要修复红黑树性质
        if (yOriginalColor == BLACK)
            deleteFixup(x);
    }
    
    // 查找节点
    bool search(T val) {
        Node<T>* result = searchHelper(root, val);
        return result != NIL;
    }
    
    // 前序遍历
    void preOrder() {
        cout << "前序遍历: ";
        preOrderHelper(root);
        cout << endl;
    }
    
    // 中序遍历
    void inOrder() {
        cout << "中序遍历: ";
        inOrderHelper(root);
        cout << endl;
    }
    
    // 后序遍历
    void postOrder() {
        cout << "后序遍历: ";
        postOrderHelper(root);
        cout << endl;
    }
    
    // 获取根节点
    Node<T>* getRoot() {
        return root;
    }
};

// 测试程序
int main() {
    RedBlackTree<int> tree;
    
    // 插入测试数据
    int values[] = {7, 3, 18, 10, 22, 8, 11, 26};
    int n = sizeof(values) / sizeof(values[0]);
    
    for (int i = 0; i < n; i++) {
        tree.insert(values[i]);
        cout << "插入 " << values[i] << " 后,中序遍历: ";
        tree.inOrder();
    }
    
    // 显示各种遍历结果
    tree.preOrder();
    tree.inOrder();
    tree.postOrder();
    
    // 查找测试
    int key = 10;
    cout << "查找 " << key << ": " << (tree.search(key) ? "找到" : "未找到") << endl;
    
    key = 15;
    cout << "查找 " << key << ": " << (tree.search(key) ? "找到" : "未找到") << endl;
    
    // 删除测试
    key = 18;
    tree.remove(key);
    cout << "删除 " << key << " 后,中序遍历: ";
    tree.inOrder();
    
    key = 3;
    tree.remove(key);
    cout << "删除 " << key << " 后,中序遍历: ";
    tree.inOrder();
    
    key = 7;
    tree.remove(key);
    cout << "删除 " << key << " 后,中序遍历: ";
    tree.inOrder();
    
    return 0;
}
    

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表