简单红黑树

自己实现的简单红黑树,有BUG或意见欢迎评论区留言

#pragma once
#include "simplequeue.h"
#include "simplestring.h"
#include "simplestack.h"
/*
* 红黑树定义    根节点为黑色
* nullptr节点算为黑色(为何如此  如果nullptr节点为红色,则子节点有nullptr的都不能为红色)
* 红色节点的两个子节点必为黑色
* 从任一节点出发到该节点下的所有叶子节点所经过的路径上的黑色节点数相同
* 
* 在删除节点时应用的关键思想,替换
*/

template <typename T>
struct SimpleRedBlackTreeNode {
	T data;
	int color;//0代表黑色,1代表红色
	SimpleRedBlackTreeNode* parent;
	SimpleRedBlackTreeNode* lNode;
	SimpleRedBlackTreeNode* rNode;
	SimpleRedBlackTreeNode<T>(T data, int color, SimpleRedBlackTreeNode* parent, SimpleRedBlackTreeNode* lNode, SimpleRedBlackTreeNode* rNode):data(data),color(color),parent(parent),lNode(lNode),rNode(rNode){}
};
template <typename T>
class SimpleRedBlackTree {
protected:
	SimpleRedBlackTreeNode<T>* root = nullptr;
    int _blackNodeNum = 0;
public:
    //将一个节点下的所有叶子节点染红
    void turnAllLeavesRed(SimpleRedBlackTreeNode<T>* currentNode);
    //判断一个节点是否有一个红色子节点
    bool hasRedChildNode(SimpleRedBlackTreeNode<T>* currentNode);
    //初始化检查
    void initCheck() { _blackNodeNum = 0; }
    //检查颜色限制
    bool checkColorLimit(SimpleRedBlackTreeNode<T>* currentNode, int blackNodeNum);
    //检查是否有连续三个黑色节点
    void checkThreeBlackNode(SimpleRedBlackTreeNode<T>* currentNode);
    //删除节点
    void removeNode(T data);
    void removeNode(SimpleRedBlackTreeNode<T>* currentNode);
    //获取特定节点
    SimpleRedBlackTreeNode<T>* getNode(T data);
    //增加节点
    void addNode(T data);
    void checkNodeColor(SimpleRedBlackTreeNode<T>* currentNode);
	SimpleRedBlackTreeNode<T>* getRoot() { return root; }
	void clear(SimpleRedBlackTreeNode<T>* n);
	SimpleRedBlackTree() {}
	~SimpleRedBlackTree() { clear(root); }
};
//清空树
template <typename T>
void SimpleRedBlackTree<T>::clear(SimpleRedBlackTreeNode<T>* n) {
    if (n == nullptr)return;
	if (n->lNode != nullptr)clear(n->lNode);
	if (n->rNode != nullptr)clear(n->rNode);
	delete n;
}
//判断一个节点是否有一个红色子节点
template <typename T>
bool SimpleRedBlackTree<T>::hasRedChildNode(SimpleRedBlackTreeNode<T>* currentNode) {
    //判断自身
    if (currentNode->color == 1)return true;
    //递归判断左子节点
    if (currentNode->lNode != nullptr) {
        if (hasRedChildNode(currentNode->lNode))return true;
    }
    //递归判断右子节点
    if (currentNode->rNode != nullptr) {
        if(hasRedChildNode(currentNode->rNode))return true;
    }
    return false;
}
//将一个节点下的所有叶子节点染红
template <typename T>
void SimpleRedBlackTree<T>::turnAllLeavesRed(SimpleRedBlackTreeNode<T>* currentNode) {
    //判断是否叶子节点
    if (currentNode->lNode == nullptr && currentNode->rNode == nullptr)currentNode->color = 1;
    else {//否则递归找到所有叶子节点
        if (currentNode->lNode != nullptr)turnAllLeavesRed(currentNode->lNode);
        if (currentNode->rNode != nullptr)turnAllLeavesRed(currentNode->rNode);
    }
}
//检查颜色限制
template <typename T>
bool SimpleRedBlackTree<T>::checkColorLimit(SimpleRedBlackTreeNode<T>* currentNode, int blackNodeNum) {
    //对空指针情形进行排除
    if (currentNode == nullptr)return true;
    //检查红色节点限制
    if (currentNode->color == 1) {
        //红色节点的子节点必为黑色
        if (currentNode->lNode != nullptr && currentNode->lNode->color == 1) {
            std::cout<< "红色节点子节点非黑" << std::endl;
            return false;
        }
        if (currentNode->rNode != nullptr && currentNode->rNode->color == 1) {
            std::cout << "红色节点子节点非黑" << std::endl;
            return false;
        }
    }
    else blackNodeNum += 1;
    //递归检查
    if (currentNode->lNode != nullptr) {
        //检查大小限制
        if (currentNode->lNode->data >= currentNode->data) {
            std::cout << "节点大小限制不合格" << std::endl;
            return false;
        }
        if(!checkColorLimit(currentNode->lNode, blackNodeNum))return false;
    }
    if (currentNode->rNode != nullptr) {
        //检查大小限制
        if (currentNode->rNode->data <= currentNode->data) {
            std::cout << "节点大小限制不合格" << std::endl;
            return false;
        }
        if (!checkColorLimit(currentNode->rNode, blackNodeNum))return false;
    }
    //在叶子节点检查黑节点数目
    if (currentNode->lNode == nullptr && currentNode->rNode == nullptr) {
        if (_blackNodeNum == 0) {
            _blackNodeNum = blackNodeNum;
            return true;
        }
        else {
            if (_blackNodeNum != blackNodeNum) {
                std::cout << "黑色节点数量不一致" << std::endl;
                return false;
            }
            else return true;
        }

    }
    else return true;
}
//检查是否有连续三个黑色节点(不含nullptr)
template <typename T>
void SimpleRedBlackTree<T>::checkThreeBlackNode(SimpleRedBlackTreeNode<T>* currentNode) {
    if (currentNode->color == 0) {
        //三个节点均为黑
        if ((currentNode->lNode != nullptr && currentNode->lNode->color == 0) && (currentNode->rNode != nullptr && currentNode->rNode->color == 0)) {
            if ((currentNode->lNode->lNode == nullptr && currentNode->lNode->rNode == nullptr) || (currentNode->rNode->lNode == nullptr && currentNode->rNode->rNode == nullptr)) {
                std::cout << "当前节点 " << currentNode->data << "子节点含自身均为黑" << "   ";
                if (currentNode->parent != nullptr) {
                    auto colorStr = currentNode->parent->color == 0 ? "黑色" : "红色";
                    std::cout << "母节点 " << currentNode->parent->data << "颜色为 " << colorStr << std::endl;
                }
                else std::cout << "母节点为空" << std::endl;
            }
        }
        if (currentNode->lNode != nullptr)checkThreeBlackNode(currentNode->lNode);
        if (currentNode->rNode != nullptr)checkThreeBlackNode(currentNode->rNode);
    }
}
//检查当前节点的红黑规则
//只检查红色节点
template <typename T>
void SimpleRedBlackTree<T>::checkNodeColor(SimpleRedBlackTreeNode<T>* currentNode) {
    if (currentNode->parent != nullptr) {
        SimpleRedBlackTreeNode<T>* parentNode = currentNode->parent;
        //连续两个节点红色,需要进行处理    由于根节点为黑色,所以currentNode->parent不可能为根节点即currentNode->parent->parent必定不为空
        if (currentNode->color == 1 && currentNode->parent->color == 1) {
            SimpleRedBlackTreeNode<T>* assistNode = parentNode->parent;
            //如果两个红色节点最近的上层黑色节点两个子节点均存在
            if (assistNode->lNode != nullptr && assistNode->rNode != nullptr) {
                //如果两个子节点均为红色
                if (assistNode->lNode->color == 1 && assistNode->rNode->color == 1) {
                    //最近的上层黑色节点变红
                    assistNode->color = 1;
                    //两个子节点变黑
                    assistNode->lNode->color = 0;
                    assistNode->rNode->color = 0;
                    checkNodeColor(assistNode);
                    return;
                }
                //如果assistNode两个子节点有一个黑色一个红色,
                else {
                    //如果parentNode位于两者中间,以parentNode代替assistNode
                    if ((parentNode->data < assistNode->data && parentNode->data > currentNode->data) || (parentNode->data > assistNode->data && parentNode->data < currentNode->data)) {
                        //parentNode替代assistNode
                        parentNode->parent = assistNode->parent;
                        if (assistNode->parent != nullptr) {
                            if (assistNode->parent->lNode == assistNode)assistNode->parent->lNode = parentNode;
                            else assistNode->parent->rNode = parentNode;
                        }
                        else root = parentNode;
                        //parentNode的子树成为assistNode的新子树
                        assistNode->parent = parentNode;
                        if (parentNode->data < assistNode->data) {//如果parentNode为assistNode的左子树  则parentNode的右子树成为为assistNode的左子树
                            if (parentNode->rNode != nullptr)parentNode->rNode->parent = assistNode;
                            assistNode->lNode = parentNode->rNode;
                            //assistNode自身成为parentNode的右子树
                            parentNode->rNode = assistNode;
                        }
                        else {//如果parentNode为assistNode的右子树  则parentNode的左子树成为为assistNode的右子树
                            if (parentNode->lNode != nullptr)parentNode->lNode->parent = assistNode;
                            assistNode->rNode = parentNode->lNode;
                            //assistNode自身成为parentNode的左子树
                            parentNode->lNode = assistNode;
                        }
                        //处理颜色变化
                        parentNode->color = 0;
                        assistNode->color = 1;
                        parentNode = parentNode->parent;
                    }
                    else {
                        //currentNode代替assistNode
                        currentNode->parent = assistNode->parent;
                        if (assistNode->parent != nullptr) {
                            if (assistNode->parent->lNode == assistNode)assistNode->parent->lNode = currentNode;
                            else assistNode->parent->rNode = currentNode;
                        }
                        else root = currentNode;
                        //currentNode为parentNode的右节点
                        if (currentNode->data > parentNode->data) {
                            //currentNode的左节点成为parentNode的右节点,currentNode的右节点成为assistNode的左节点
                            if (currentNode->lNode != nullptr)currentNode->lNode->parent = parentNode;
                            if (currentNode->rNode != nullptr)currentNode->rNode->parent = assistNode;
                            parentNode->rNode = currentNode->lNode;
                            assistNode->lNode = currentNode->rNode;
                            //parentNode和assistNode分别成为currentNode的左右节点
                            parentNode->parent = currentNode;
                            assistNode->parent = currentNode;
                            currentNode->lNode = parentNode;
                            currentNode->rNode = assistNode;
                        }
                        //currentNode为parentNode的左节点
                        else {
                            //currentNode的左节点成为assistNode的右节点,currentNode的右节点成为parentNode的左节点
                            if (currentNode->lNode != nullptr)currentNode->lNode->parent = assistNode;
                            if (currentNode->rNode != nullptr)currentNode->rNode->parent = parentNode;
                            assistNode->rNode = currentNode->lNode;
                            parentNode->lNode = currentNode->rNode;
                            //assistNode和parentNode分别成为currentNode的左右节点
                            parentNode->parent = currentNode;
                            assistNode->parent = currentNode;
                            currentNode->rNode = parentNode;
                            currentNode->lNode = assistNode;
                        }
                        //颜色处理
                        currentNode->color = 0;
                        assistNode->color = 1;
                        //查找下一个红色节点
                        parentNode = currentNode->parent;
                    } 
                }
            }//如果两个红色节点最近的上层黑色节点只有一个子节点
            else {//统一所有旋转方式   由于已经记录了三个关键节点   对其进行排序
                SimpleRedBlackTreeNode<T>* maxNode = nullptr;
                SimpleRedBlackTreeNode<T>* middleNode = nullptr;
                SimpleRedBlackTreeNode<T>* minNode = nullptr;
                //第一次比较
                if (currentNode->data > parentNode->data) {
                    maxNode = currentNode;
                    middleNode = parentNode;
                }
                else {
                    maxNode = parentNode;
                    middleNode = currentNode;
                }
                //第二次比较  找出max
                if (assistNode->data > maxNode->data) {
                    minNode = maxNode;
                    maxNode = assistNode;
                }
                else {
                    minNode = assistNode;
                }
                //第三次比较
                if (minNode->data > middleNode->data) {
                    SimpleRedBlackTreeNode<T>* temp = middleNode;
                    middleNode = minNode;
                    minNode = temp;
                }
                //middleNode换到assistNode的位置
                if (assistNode->parent != nullptr) {
                    //连接需要双向更新
                    if (assistNode->parent->lNode == assistNode)assistNode->parent->lNode = middleNode;
                    else assistNode->parent->rNode = middleNode;
                    middleNode->parent = assistNode->parent;
                }
                else {
                    this->root = middleNode;
                    middleNode->parent = nullptr;
                }
                //minNode成为middleNode的左子节点
                minNode->parent = middleNode;
                middleNode->lNode = minNode;
                //maxNode成为middleNode的右子节点
                maxNode->parent = middleNode;
                middleNode->rNode = maxNode;
                //minNode和maxNode子节点清空
                minNode->lNode = nullptr;
                minNode->rNode = nullptr;
                maxNode->lNode = nullptr;
                maxNode->rNode = nullptr;
                //更新颜色信息 全部置为黑色,则需要相应更新其它地方的非黑节点
                middleNode->color = 0;
                minNode->color = 1;
                maxNode->color = 1;
                parentNode = middleNode->parent;
            }
        }//找到下一个红色节点
        //跳过所有黑色节点
        while (parentNode != nullptr && parentNode->color == 0)parentNode = parentNode->parent;
        //如果找到下一个红色节点,进行检查
        if (parentNode != nullptr)checkNodeColor(parentNode);
    }
    else {//说明为根元素
        if (currentNode->color == 1)currentNode->color = 0;//根元素只能为黑色
    }
}
//增加节点    所有叶子都是黑色(叶子是NIL节点)
template <typename T>
void SimpleRedBlackTree<T>::addNode(T data){
    if (this->root == nullptr) {
        this->root = new SimpleRedBlackTreeNode<T>(data, 0, nullptr, nullptr, nullptr);
    }
    else {
        SimpleRedBlackTreeNode<T>* currentNode = this->root;
        while (true) {
            //比较该数据与当前节点的数值
            if (data >= currentNode->data) {
                //如果大于等于且当前节点右值为空,插入
                if (currentNode->rNode == nullptr) {
                    currentNode->rNode = new SimpleRedBlackTreeNode<T>(data, 1, currentNode, nullptr, nullptr);
                    checkNodeColor(currentNode->rNode);
                    return;
                }
                else currentNode = currentNode->rNode;//如果大于等于但当前节点右值非空,继续比较
            }
            else {
                //如果大于等于且当前节点左值为空,插入
                if (currentNode->lNode == nullptr) {
                    currentNode->lNode = new SimpleRedBlackTreeNode<T>(data, 1, currentNode, nullptr, nullptr);
                    checkNodeColor(currentNode->lNode);
                    return;
                    //如果大于等于但当前节点左值非空,继续比较
                }
                else currentNode = currentNode->lNode;
            }
        }
    }
}
//删除节点
template <typename T>
void SimpleRedBlackTree<T>::removeNode(T data) {
    if (this->root == nullptr)return;
    else {
        SimpleRedBlackTreeNode<T>* node = getNode(data);
        if (node != nullptr)removeNode(node);
    }
}
template <typename T>
void SimpleRedBlackTree<T>::removeNode(SimpleRedBlackTreeNode<T>* currentNode) {
    if (currentNode != nullptr) {
        SimpleRedBlackTreeNode<T>* parentNode = currentNode->parent;
        if (currentNode->lNode != nullptr && currentNode->rNode != nullptr) {
            //找到前驱节点
            SimpleRedBlackTreeNode<T>* frontDriveNode = currentNode->lNode;
            while (frontDriveNode->rNode != nullptr)frontDriveNode = frontDriveNode->rNode;
            //保留currentNode但更新数据信息
            currentNode->data = frontDriveNode->data;
            //删除前驱节点
            removeNode(frontDriveNode);
            return;//跳过删除当前节点
        }//删除的节点只有一个子节点时,删除节点只能是黑色,子节点也只能是红色
        else if ((currentNode->lNode != nullptr && currentNode->rNode == nullptr) || (currentNode->lNode == nullptr && currentNode->rNode != nullptr)) {
            SimpleRedBlackTreeNode<T>* childNode = currentNode->lNode != nullptr ? currentNode->lNode : currentNode->rNode;
            //childNode成为parentNode的子节点
            childNode->parent = parentNode;
            //需要考虑currentNode是否为根节点
            if (parentNode != nullptr) {//currentNode非根节点
                if (parentNode->lNode == currentNode)parentNode->lNode = childNode;
                else parentNode->rNode = childNode;
            }else root = childNode;//currentNode为根节点
            //修改childNode颜色
            childNode->color = 0;
        }//如果两个子节点均空,说明为叶子节点
        else {
            //如果为红色节点,直接删除   根节点不可能为红色 故currentNode->parent 非空
            if (currentNode->color == 1) {
                if (currentNode->parent->lNode == currentNode)currentNode->parent->lNode = nullptr;
                else currentNode->parent->rNode = nullptr;
            }
            else {//如果当前节点为黑色   根据从任一节点出发到该节点下的所有叶子节点所经过的路径上的黑色节点数相同 故另一节点不可能为空
                //推断二 如兄弟节点为红色,则其两子节点必存在
                // 兄弟节点为黑色则必无孙子节点
                if (currentNode->parent == nullptr)root = nullptr;//当前节点为根节点
                else {
                    //记录兄弟节点
                    SimpleRedBlackTreeNode<T>* assistNode = nullptr;
                    if (parentNode->lNode == currentNode) {
                        assistNode = parentNode->rNode;
                        //断开和当前节点的连接
                        parentNode->lNode = nullptr;
                    }
                    else {
                        assistNode = parentNode->lNode;
                        //断开和当前节点的连接
                        parentNode->rNode = nullptr;
                    }
                    if (assistNode->lNode != nullptr && assistNode->rNode != nullptr) {
                        //如果assistNode的两个节点都存在  找到parentNode的前驱或后继节点(根据assistNode和parentNode的相对位置决定),由该节点替代parentNode,parentNode替代currentNode
                        SimpleRedBlackTreeNode<T>* newParentNode = nullptr;
                        if (parentNode->lNode == assistNode) {
                            //由于拓扑基本不变,不重新分配空间 重连上当前节点的连接
                            parentNode->rNode = currentNode;
                            //找到前驱节点
                            newParentNode = assistNode;
                            while (newParentNode->rNode != nullptr)newParentNode = newParentNode->rNode;
                        }
                        else {
                            //由于拓扑基本不变,不重新分配空间 重连上当前节点的连接
                            parentNode->lNode = currentNode;
                            //找到后继节点
                            newParentNode = assistNode;
                            while (newParentNode->lNode != nullptr)newParentNode = newParentNode->lNode;
                        }
                        //parentNode替代currentNode
                        currentNode->data = parentNode->data;
                        //找到parentNode的前驱或后继节点(根据assistNode和parentNode的相对位置决定),由该节点替代parentNode                        
                        parentNode->data = newParentNode->data;
                        //删除替代parentNode的节点
                        removeNode(newParentNode);
                        return;//跳过删除当前节点
                    }//如果assistNode的两个子节点都不存在   则assistNode必为黑色
                    else if (assistNode->lNode == nullptr && assistNode->rNode == nullptr) {
                        //如果parentNode的颜色为红色
                        if (parentNode->color == 1) {
                            //parentNode改为黑色,assistNode改为红色即可
                            parentNode->color = 0;
                            assistNode->color = 1;
                        }
                        else {//如果parentNode的颜色为黑色
                            if (parentNode->parent == nullptr) {//如果parentNode为根节点
                                assistNode->color = 1;
                            }
                            else {
                                //找到grandmaNode的后继/前驱节点(根据grandmaNode和parentNode的相对位置决定),由该节点替代grandmaNode
                                //由grandmaNode代替代替被删除的节点       可能出BUG的情况,当grandmaNode的左右子树对称,会进入无休止的递归调用
                                SimpleRedBlackTreeNode<T>* grandmaNode = parentNode->parent;//grandmaNode的另一子树必不为空
                                SimpleRedBlackTreeNode<T>* uncleNode = grandmaNode->lNode == parentNode ? grandmaNode->rNode : grandmaNode->lNode;
                                //向上递归的条件   uncleNode为黑色节点且无红色后代节点(当uncleNode本身为红色或有红色后代节点,可统一处理方式) 无需顾及grandmaNode是否为非根节点或颜色是否为黑色
                                //grandmaNode为非根节点   当grandmaNode为根节点,uncleNode为黑色节点且无红色后代节点,可统一处理方式,所有叶子节点变红
                                //grandmaNode节点颜色为黑色        当grandmaNode节点颜色为红色,则必然非根节点,若uncleNode为黑色节点且无红色后代节点,可统一处理方式,grandmaNode节点变红,grandmaNode节点下所有叶子节点变红
                                //由于需要循环的修改需要将经过的每个grandmaNode记起来
                                SimpleStack<SimpleRedBlackTreeNode<T>* > ssGrandmaNode = SimpleStack<SimpleRedBlackTreeNode<T>* >();
                                SimpleStack<SimpleRedBlackTreeNode<T>* > ssUncleNode = SimpleStack<SimpleRedBlackTreeNode<T>* >();
                                ssGrandmaNode.push(grandmaNode);
                                ssUncleNode.push(uncleNode);
                                while (!hasRedChildNode(uncleNode) && grandmaNode->parent != nullptr && grandmaNode->color == 0 ) {
                                    SimpleRedBlackTreeNode<T>* temp = grandmaNode;
                                    grandmaNode = grandmaNode->parent;
                                    ssGrandmaNode.push(grandmaNode);
                                    uncleNode = grandmaNode->lNode == temp ? grandmaNode->rNode : grandmaNode->lNode;
                                    ssUncleNode.push(uncleNode);
                                }
                                //对终结条件进行分类处理  uncleNode本身为红色或有红色后代节点
                                if (hasRedChildNode(uncleNode)) {
                                    T finalData;
                                    //处理直到栈空
                                    while (!ssGrandmaNode.isEmpty()) {
                                        //获取数据
                                        grandmaNode = ssGrandmaNode.pop();
                                        uncleNode = ssUncleNode.pop();
                                        //根据位置判断应该找前驱还是后继
                                        if (grandmaNode->lNode == uncleNode) {
                                            //找前驱节点
                                            while (uncleNode->rNode != nullptr)uncleNode = uncleNode->rNode;
                                        }
                                        else {
                                            //找后继节点
                                            while (uncleNode->lNode != nullptr)uncleNode = uncleNode->lNode;
                                        }
                                        //找出来的节点替代grandmaNode
                                        T data = grandmaNode->data;
                                        grandmaNode->data = uncleNode->data;
                                        //删除找出来的节点
                                        removeNode(uncleNode);
                                        //将grandmaNode的值重新加入
                                        if (!ssGrandmaNode.isEmpty())addNode(data);
                                        else finalData = data;
                                    }
                                    //重新连上parentNode和currentNode
                                    if (parentNode->lNode == assistNode) {
                                        //由于拓扑基本不变,不重新分配空间 重连上当前节点的连接
                                        parentNode->rNode = currentNode;
                                    }
                                    else {
                                        //由于拓扑基本不变,不重新分配空间 重连上当前节点的连接
                                        parentNode->lNode = currentNode;
                                    }
                                    T max;
                                    T middle;
                                    T min;
                                    //用data的值替代currentNode的值   排序出max middle min
                                    if (finalData > parentNode->data) {
                                        max = finalData;
                                        middle = parentNode->data;
                                    }
                                    else {
                                        max = parentNode->data;
                                        middle = finalData;
                                    }
                                    if (max > assistNode->data) {
                                        min = assistNode->data;
                                    }
                                    else {
                                        min = max;
                                        max = assistNode->data;
                                    }
                                    if (min > middle) {
                                        T temp = middle;
                                        middle = min;
                                        min = temp;
                                    }
                                    //进行修改
                                    parentNode->data = middle;
                                    parentNode->lNode->data = min;
                                    parentNode->rNode->data = max;
                                    return;
                                }else if (grandmaNode->parent == nullptr) {//终结点grandmaNode为根节点
                                    turnAllLeavesRed(grandmaNode);
                                }
                                else if (grandmaNode->color == 1) {//终结点为grandmaNode节点颜色为红色
                                    grandmaNode->color = 0;
                                    turnAllLeavesRed(grandmaNode);
                                }
                            }                            
                        }
                    }//如果assistNode的两个子节点只存在一个,则assistNode必为黑色节点,该子节点必为红色
                    else {
                        SimpleRedBlackTreeNode<T>* nephewNode = assistNode->lNode != nullptr ? assistNode->lNode : assistNode->rNode;
                        //如果assistNode的只有一个节点存在
                        SimpleRedBlackTreeNode<T>* maxNode = nullptr;
                        SimpleRedBlackTreeNode<T>* middleNode = nullptr;
                        SimpleRedBlackTreeNode<T>* minNode = nullptr;
                        //第一次比较 取出二者的较大值
                        if (assistNode->data > parentNode->data) {
                            maxNode = assistNode;
                            middleNode = parentNode;
                        }
                        else {
                            maxNode = parentNode;
                            middleNode = assistNode;
                        }
                        //第二次比较  确认最大值
                        if (maxNode->data > nephewNode->data) {
                            minNode = nephewNode;
                        }
                        else {
                            minNode = maxNode;
                            maxNode = nephewNode;
                        }
                        //第三次比较 对剩下两个排序
                        if (minNode->data > middleNode->data) {
                            SimpleRedBlackTreeNode<T>* temp = minNode;
                            minNode = middleNode;
                            middleNode = temp;
                        }
                        //middleNode取代parentNode
                        middleNode->parent = parentNode->parent;
                        if (parentNode->parent != nullptr) {
                            if (parentNode->parent->lNode == parentNode)parentNode->parent->lNode = middleNode;
                            else parentNode->parent->rNode = middleNode;
                        }else root = middleNode;
                        //minNode和maxNode分别成为middleNode的左右子节点
                        minNode->parent = middleNode;
                        middleNode->lNode = minNode;
                        maxNode->parent = middleNode;
                        middleNode->rNode = maxNode;
                        //minNode和maxNode子节点清空
                        minNode->lNode = nullptr;
                        minNode->rNode = nullptr;
                        maxNode->lNode = nullptr;
                        maxNode->rNode = nullptr;
                        //确认颜色改变
                        middleNode->color = parentNode->color;
                        minNode->color = 0;
                        maxNode->color = 0;
                    }
                }
            }
        }
        delete currentNode;
    }
}
//获取特定节点
template <typename T>
SimpleRedBlackTreeNode<T>* SimpleRedBlackTree<T>::getNode(T data) {
    if (this->root == nullptr)return nullptr;
    else {
        SimpleRedBlackTreeNode<T>* currentNode = this->root;
        //遍历AVL树,找到匹配的节点
        while (true) {
            if (data == currentNode->data) {
                return currentNode;
            }
            else if (data > currentNode->data) {
                if (currentNode->rNode != nullptr)currentNode = currentNode->rNode;
                else return nullptr;
            }
            else {
                if (currentNode->lNode != nullptr)currentNode = currentNode->lNode;
                else return nullptr;
            }
        }
    }
}
class SimpleIntRedBlackTree : public SimpleRedBlackTree<int> {
public:
	void iteratorTreeString(SimpleRedBlackTreeNode<int>* currentNode);
	char* toString();
	char* colorToString();
	SimpleIntRedBlackTree() {}
	~SimpleIntRedBlackTree() {}
};
void SimpleIntRedBlackTree::iteratorTreeString(SimpleRedBlackTreeNode<int>* currentNode) {
    if (currentNode->lNode != nullptr)iteratorTreeString(currentNode->lNode);
    std::cout << currentNode->data;
    if (currentNode->rNode != nullptr)iteratorTreeString(currentNode->rNode);
}
char* SimpleIntRedBlackTree::toString() {
    if (root == nullptr) {
        SimpleString str = SimpleString("空树");
        return str.getData();
    }
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* ss = new SimpleQueue<SimpleRedBlackTreeNode<int>*>();
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* ssNext = new SimpleQueue<SimpleRedBlackTreeNode<int>*>();
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* temp = nullptr;
    SimpleRedBlackTreeNode<int>* n = nullptr;
    ss->push(root);
    SimpleStringBuilder strBuilder;
    SimpleString layerInsideGap = SimpleString(" ");
    SimpleString layerGap = SimpleString("\n");
    while (true) {
        while (!ss->isEmpty()) {
            n = ss->pop_back();
            if (n->lNode != nullptr)ssNext->push(n->lNode);
            if (n->rNode != nullptr)ssNext->push(n->rNode);
            SimpleString data = SimpleString((long)n->data);
            strBuilder.append(layerInsideGap);
            strBuilder.append(data);
        }
        if (!ssNext->isEmpty()) {
            temp = ss;
            ss = ssNext;
            ssNext = temp;
            strBuilder.append(layerGap);
        }
        else break;
    }
    int length = strBuilder.getLength();
    char* s = new char[length + 1];
    memcpy(s, strBuilder.getData(), length);
    s[length] = 0;
    //释放空间
    delete ss;
    delete ssNext;
    return s;
}
char* SimpleIntRedBlackTree::colorToString() {
    if (root == nullptr) {
        SimpleString str = SimpleString("空树");
        return str.getData();
    }
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* ss = new SimpleQueue<SimpleRedBlackTreeNode<int>*>();
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* ssNext = new SimpleQueue<SimpleRedBlackTreeNode<int>*>();
    SimpleQueue<SimpleRedBlackTreeNode<int>*>* temp = nullptr;
    SimpleRedBlackTreeNode<int>* n = nullptr;
    ss->push(root);
    SimpleStringBuilder strBuilder;
    SimpleString layerInsideGap = SimpleString(" ");
    SimpleString layerGap = SimpleString("\n");
    while (true) {
        while (!ss->isEmpty()) {
            n = ss->pop_back();
            if (n->lNode != nullptr)ssNext->push(n->lNode);
            if (n->rNode != nullptr)ssNext->push(n->rNode);
            SimpleString data = SimpleString((long)n->color);
            strBuilder.append(layerInsideGap);
            strBuilder.append(data);
        }
        if (!ssNext->isEmpty()) {
            temp = ss;
            ss = ssNext;
            ssNext = temp;
            strBuilder.append(layerGap);
        }
        else break;
    }
    int length = strBuilder.getLength();
    char* s = new char[length + 1];
    memcpy(s, strBuilder.getData(), length);
    s[length] = 0;
    //释放空间
    delete ss;
    delete ssNext;
    return s;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔡海航

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值