基于C++的红黑树代码

#include<iostream>
#include<vector>
using namespace std;

//模板的创建
template <class K, class V>
//类的创建
class RBtree {
public:
    RBtree() { cout << "构建了红黑树的类" << endl; }
    //嵌套类
    class RBnode {
    public:
        //构造函数的重载
        RBnode(K key, V value, RBnode* parent, RBnode* left, RBnode* right, bool color) : key(key), value(value), parent(parent), left(left), right(right), color(color) { cout << "内部类被创建" << endl; }
        RBnode(K key, V value) : key(key), value(value), parent(nullptr), left(nullptr), right(nullptr), color(false) {}
        RBnode* parent;
        RBnode* left;
        RBnode* right;
        bool color;
        K key;
        V value;
    };
    const bool RED = false;
    const bool BLACK = true;
    RBnode* root = nullptr;
    //左旋函数
    void leftRotate(RBnode* node) {
        if (node != nullptr) {
            RBnode* rightChild = node->right;
            node->right = rightChild->left;
            if (rightChild->left != nullptr) {
                rightChild->left->parent = node;
            }
            rightChild->parent = node->parent;
            if (node->parent == nullptr) {
                root = rightChild;
            }
            else if (node == node->parent->left) {
                node->parent->left = rightChild;
            }
            else {
                node->parent->right = rightChild;
            }
            rightChild->left = node;
            node->parent = rightChild;
        }
    }
    //右旋函数
    void rightRotate(RBnode* node) {
        if (node != nullptr) {
            RBnode* leftChild = node->left;
            node->left = leftChild->right;
            if (leftChild->right != nullptr) {
                leftChild->right->parent = node;
            }
            leftChild->parent = node->parent;
            if (node->parent == nullptr) {
                root = leftChild;
            }
            else if (node == node->parent->right) {
                node->parent->right = leftChild;
            }
            else {
                node->parent->left = leftChild;
            }
            leftChild->right = node;
            node->parent = leftChild;
        }
    }
public:
    //操作函数
    //获取父节点
    RBnode* parentOfTree(RBnode* RBnode) {
        return RBnode == nullptr ? nullptr : RBnode->parent;
    }
    //获取左节点
    RBnode* leftOfTree(RBnode* RBnode) {
        return RBnode == nullptr ? nullptr : RBnode->left;
    }
    //获取右节点
    RBnode* rightOfTree(RBnode* RBnode) {
        return RBnode == nullptr ? nullptr : RBnode->right;
    }
    //获取颜色
    bool colorOfTree(RBnode* node) {
        return node == nullptr ? BLACK : node->color;
    }
    //设置节点的颜色
    void setColorOfTree(RBnode* RBnode, bool color) {
        if (RBnode != nullptr) {
            RBnode->color = color;
        }
    }
    //获取根节点
    RBnode* getTreeRoot() {
        return RBtree::root;
    }
    //中序遍历
    void showTree(RBnode* showRoot) {
        if (showRoot != nullptr) {
            showTree(showRoot->left);
            cout << showRoot->key << " ";
            showTree(showRoot->right);
        }
    }
    //生成的二叉树展示
    void printTree(RBnode* root, int level) {
        if (root == nullptr) {
            return;
        }
        printTree(root->right, level + 1);
        for (int i = 0; i < level; i++) {
            std::cout << "    ";
        }
        std::cout << root->key << "," << root->color << "\n";
        printTree(root->left, level + 1);
    }
    //选择创建二叉树的key值
    void createTree() {
        int input;
        std::cout << "Enter Nodes (enter 0 to finish):" << endl;
        while (true) {
            std::cin >> input;
            if (input == 0) {
                break;
            }
            RBtree::newNode(input, input);
        }
    }
    //新节点创建函数
    void newNode(K newKey, V newValue) {
        //1.找到插入节点的位置
        RBnode* getRoot = this->root;
        RBnode* parent = nullptr;
        while (getRoot != nullptr) {
            parent = getRoot;
            if (newKey < getRoot->key) {
                getRoot = getRoot->left;
            }
            else if (newKey > getRoot->key) {
                getRoot = getRoot->right;
            }
            else {
                getRoot->value = newValue;
                return;
            }
        }
        RBnode* newNode = new RBnode(newKey, newValue);
        newNode->parent = parent;
        if (parent == nullptr) {
            root = newNode;
        }
        else if (newKey < parent->key) {
            parent->left = newNode;
        }
        else {
            parent->right = newNode;
        }
        //2.旋转变色,构建红黑树
        fixTheTree(newNode);
    }
  //由2-3-4树入手分析得到8种需要调整的红黑树
    void fixTheTree(RBnode* node) {
        node->color = RED;//要插入的节点肯定为红色
        //依次排除空节点,根节点,二次节点,因为不需要操作。
       while(node != nullptr && node != root && node->parent->color == RED) {
            //
            if (RBtree::parentOfTree(node) == RBtree::leftOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)))) {
                RBnode* tempNode = RBtree::rightOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)));
                if (RBtree::colorOfTree(tempNode) == RED) {
                    //有叔叔节点
                    //变色+递归
                    //父亲和叔叔变为黑色 爷爷变为红色
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(tempNode, BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)), RED);
                    node = RBtree::parentOfTree(RBtree::parentOfTree(node));
                    
                }
                else {
                    //没有叔叔节点
                    if (node == node->parent->right) {
                        node = RBtree::parentOfTree(node);
                        RBtree::leftRotate(node);
                    }
                    //父亲节点变为黑色 爷爷节点变为红色
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)), RED);
                    //根据爷爷节点左右旋操作
                    RBtree::rightRotate(RBtree::parentOfTree(RBtree::parentOfTree(node)));  
                }
            }
            else {
                RBnode* tempNode = RBtree::leftOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)));
                if (RBtree::colorOfTree(tempNode) == RED) {
                    //有叔叔节点
                    //变色+递归
                    //父亲和叔叔变为黑色 爷爷变为红色
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(tempNode, BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)), RED);
                    node = RBtree::parentOfTree(RBtree::parentOfTree(node));
                }
                else {
                    //没有叔叔节点
                    if (node == node->parent->left) {
                        node = RBtree::parentOfTree(node);
                        RBtree::rightRotate(node);
                    }
                    //父亲节点变为黑色 爷爷节点变为红色
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(RBtree::parentOfTree(node)), RED);
                    //根据爷爷节点左右旋操作
                    RBtree::leftRotate(RBtree::parentOfTree(RBtree::parentOfTree(node))); 
                }
            }
        }
       RBtree::root->color = BLACK;
    }


    //删除节点对删除后的二叉树进行调整
    void fixAfterRemove(RBnode* node) {
        while (node != root && RBtree::colorOfTree(node) == BLACK) {
            if (RBtree::leftOfTree(RBtree::parentOfTree(node)) == node) {
                //1.找到兄弟节点
                RBnode* rNode = RBtree::parentOfTree(node)->right;
                //判断是不是真正的兄弟节点
                if (RBtree::colorOfTree(rNode) == RED) {
                    //找到的不是真正的兄弟节点
                    RBtree::setColorOfTree(rNode, BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), RED);
                    RBtree::leftRotate(RBtree::parentOfTree(node));
                    rNode = RBtree::parentOfTree(node)->right;
                }
                //当兄弟节点一个子节点都没有的情况下不借
                if (RBtree::colorOfTree(RBtree::leftOfTree(rNode)) == BLACK && RBtree::colorOfTree(RBtree::rightOfTree(rNode)) == BLACK) {
                    //兄弟节点不借
                    RBtree::setColorOfTree(rNode, RED);
                    node = RBtree::parentOfTree(node);
                }
                else {
                    //兄弟节点借
                    //如果兄弟节点的子节点是其左子节点,需要先变色 完成右转一次
                    if (RBtree::colorOfTree(RBtree::rightOfTree(rNode)) == BLACK) {
                        //右侧节点为空,那么左侧子节点肯定不为空
                        RBtree::setColorOfTree(rNode, RED);
                        RBtree::setColorOfTree(RBtree::leftOfTree(rNode), BLACK);
                        RBtree::rightRotate(rNode);
                        rNode = RBtree::rightOfTree(RBtree::parentOfTree(node));
                    }
                    //需要根据父节点做一次左旋操作 变色
                    RBtree::setColorOfTree(rNode, RBtree::colorOfTree(RBtree::parentOfTree(node)));
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(RBtree::rightOfTree(rNode), BLACK);
                    RBtree::leftRotate(RBtree::parentOfTree(node));
                    node = root;
                }
            }
            else {
                //1.找到兄弟节点
                RBnode* rNode = RBtree::parentOfTree(node)->left;
                //判断是不是真正的兄弟节点
                if (RBtree::colorOfTree(rNode) == RED) {
                    //找到的不是真正的兄弟节点
                    RBtree::setColorOfTree(rNode, BLACK);
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), RED);
                    RBtree::rightRotate(RBtree::parentOfTree(node));
                    rNode = RBtree::parentOfTree(node)->left;
                }
                //当兄弟节点一个子节点都没有的情况下不借
                if (RBtree::colorOfTree(RBtree::rightOfTree(rNode)) == BLACK && RBtree::colorOfTree(RBtree::leftOfTree(rNode)) == BLACK) {
                    //兄弟节点不借
                    RBtree::setColorOfTree(rNode, RED);
                    node = RBtree::parentOfTree(node);
                }
                else {
                    //兄弟节点借
                    //如果兄弟节点的子节点是其左子节点,需要先变色 完成右转一次
                    if (RBtree::colorOfTree(RBtree::leftOfTree(rNode)) == BLACK) {
                        //右侧节点为空,那么左侧子节点肯定不为空
                        RBtree::setColorOfTree(rNode, RED);
                        RBtree::setColorOfTree(RBtree::rightOfTree(rNode), BLACK);
                        RBtree::leftRotate(rNode);
                        rNode = RBtree::leftOfTree(RBtree::parentOfTree(node));
                    }
                    //需要根据父节点做一次左旋操作 变色
                    RBtree::setColorOfTree(rNode, RBtree::colorOfTree(RBtree::parentOfTree(node)));
                    RBtree::setColorOfTree(RBtree::parentOfTree(node), BLACK);
                    RBtree::setColorOfTree(RBtree::leftOfTree(rNode), BLACK);
                    RBtree::rightRotate(RBtree::parentOfTree(node));
                    node = root;
                }

            }
        }

        RBtree::setColorOfTree(node, BLACK); 
    }

    //选择要删除的key值
    void removeTree() {
        int input;
        std::cout << "Enter Nodes to Remove (enter 0 to finish):" << endl;
        while (true) {
            std::cin >> input;
            if (input == 0) {
                break;
            }
            RBtree::remove(input);
        }
    }
    //查找前驱节点
    RBnode* preNode(RBnode* node) {
        if (node == nullptr) {
            return nullptr;
        }
        else if (node->left != nullptr) {
            //左子节点不为空
            RBnode* tempnode = RBtree::leftOfTree(node);
            while (RBtree::rightOfTree(node) != nullptr) {
                tempnode = RBtree::rightOfTree(tempnode);
            }
            return tempnode;
        }
        else {
            //node没有左子节点只能向上找
            RBnode* tempnode = node->parent;
            RBnode* tempNode = node;
            while (tempnode != nullptr && tempNode == RBtree::leftOfTree(tempnode)) {
                tempNode = tempnode;
                tempnode = RBtree::parentOfTree(tempnode);
            }
            return tempnode;
        }
        
    }
    //查找后继节点
    RBnode* AfterNode(RBnode* node) {
        if (node == nullptr) {
            return nullptr;
        }
        else if (node->right != nullptr) {
            //右子节点不为空
            RBnode* tempnode = RBtree::rightOfTree(node);
            while (RBtree::leftOfTree(tempnode) != nullptr) {
                tempnode = RBtree::leftOfTree(tempnode);
            }
            return tempnode;
        }
        else {
            //node没有左子节点只能向上找
            RBnode* tempnode = node->parent;
            RBnode* tempNode = node;
            while (tempnode != nullptr && tempNode == RBtree::rightOfTree(tempnode)) {
                tempNode = tempnode;
                tempnode = RBtree::parentOfTree(tempnode);
            }
            return tempnode;
        }
    }

    //找到某个key对应的节点
    RBnode* getNode(K key) {
        RBnode* node = this->root;
        while (node!=nullptr) {
            if (key < node->key) {
                node = node->left;
            }
            else if (key > node->key) {
                node = node->right;
            }
            else {
                return node;
            }
        }
        return nullptr;
    }
    //删除节点
    void deletNode(RBnode* node) {
        if (RBtree::leftOfTree(node) != nullptr && RBtree::rightOfTree(node) != nullptr) {
            //说明要删除的节点有两个子节点,需要找到后继、前驱节点
            RBnode* Pnode = RBtree::AfterNode(node);
            //用后继节点的值覆盖父节点
            node->key = Pnode->key;
            node->value = Pnode->value;
            node = Pnode;
        }
        RBnode* replacement = node->left != nullptr ? node->left : node->right;//找到删除之后其左、右节点
        if (replacement != nullptr) {
            replacement->parent = node->parent;//将删除节点的父节点给剩下的子节点
            if (node->parent == nullptr) {
                //说明删除的为根节点
                root = replacement;
            }
            else if (RBtree::leftOfTree(RBtree::parentOfTree(node)) == node) {
                //此时删除的节点为其父节点的左节点,需要将replacement幅值到其删除节点的父节点的左子节点
                RBtree::parentOfTree(node)->left = replacement;
            }
            else {
                RBtree::parentOfTree(node)->right = replacement;
            }
            //删除节点GC回收
            node->left = node->right = node->parent = nullptr;
            if (RBtree::colorOfTree(node) == BLACK) {
                fixAfterRemove(replacement);//删除后的调整
            }
        }
        else if (node->parent == nullptr) {
            //说明删除的就是root节点
            root = nullptr;
        }
        else {
            if (node->color == BLACK) {
                fixAfterRemove(node);//删除后的调整
            }
            if (node->parent != nullptr) {
                if (RBtree::leftOfTree(RBtree::parentOfTree(node)) == node) {
                    RBtree::parentOfTree(node)->left = nullptr;
                }
                else {
                    RBtree::parentOfTree(node)->right = nullptr;
                }
                node = nullptr;
            }
        }

    }
    //红黑树的节点删除
    void remove(K key) {
        RBnode* node = getNode(key);
        if (node != nullptr) {
            deletNode(node);
        }
    }
};


int main()
{
    char a;
    RBtree<int, int> T;
    while (1) {
        T.createTree();
        T.printTree(T.getTreeRoot(), 0);
        T.removeTree();
        T.printTree(T.getTreeRoot(), 0);
    }
    return 0;
}

代码运行展示:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值