红黑树C++代码 , 没优化,冗余太多,暂时是草稿一类

#include<iostream>
using namespace std;


#define DEFAULT 333
enum colour{red,black};
class rd;
class node
{
private:
    colour color;
    node *lchild;
    node *rchild;
    node *parent;
    int key;
    //T data;      //可以以后加
public:
    node(int k, colour c = red) :color(c), key(k), lchild(NULL), rchild(NULL), parent(NULL){}
    node(){}
    ~node(){}

    friend class rd;
};

class rd
{
private:
    node *root;
public:
    rd() :root(NULL){}
    ~rd(){}

    bool Insert(const int k);      //往红黑树中插入节点
    void Insert_adjust(node *curr);      //节点插入调整
    node* L_rotate(node *curr);      //左旋 并返回新根节点
    node* R_rotate(node *curr);      //右旋 并返回新根节点
    node* Search(const int k);      //查找节点并返回节点
    void In_order(node *curr);      //中序遍历
    void Pre_order(node *curr);     //先序遍历
    void Level_order();      //层序遍历
    void Visit(node *curr);      //输出节点信息
    node* Get_root();      //获取根节点
    void Remove(const int k);      //删除节点
    void Delete_adjust(node *d);      //节点删除调整
    void DB_adjust(node *curr);      //待删节点的父-兄弟皆为黑节点,且兄弟节点没有孩子的情况调整
    void IN()      //仅为测试而已 观察根节点地址是否被替换
    {
        In_order(root);
    }      
};

inline node* rd::Get_root()
{
    return root;
}
inline void rd::Visit(node *curr)
{
    cout << " " << curr->key << "-" << curr->color;
}
void rd::In_order(node *curr)
{
    if (curr == NULL)
    {
        return;
    }
    In_order(curr->lchild);
    Visit(curr);
    In_order(curr->rchild);
}
void rd::Pre_order(node *curr)
{
    if (curr == NULL)
    {
        return;
    }
    Visit(curr);
    Pre_order(curr->lchild);
    Pre_order(curr->rchild);
}
void rd::Level_order()
{
    if (root == NULL)
    {
        cout << "红黑树为空,层序遍历失败!" << endl;
        return;
    }
    node **qu = new node*[DEFAULT];
    int front, rear;
    front = rear = 0;
    qu[front] = qu[rear++] = root;      //队列留一个空间做判定条件
    while (front != rear)
    {
        node *curr = qu[front];
        Visit(curr);
        front = (front + 1) % DEFAULT;
        if (curr->lchild != NULL)
        {
            if ((rear + 1) % DEFAULT == front)
            {
                cout << "队列空间过小,遍历失败!" << endl;
                return;
            }
            qu[rear] = curr->lchild;
            rear = (rear + 1) % DEFAULT;
        }
        if (curr->rchild != NULL)
        {
            if ((rear + 1) % DEFAULT == front)
            {
                cout << "队列空间过小,遍历失败!" << endl;
                return;
            }
            qu[rear] = curr->rchild;
            rear = (rear + 1) % DEFAULT;
        }
    }
}
bool rd::Insert(const int k)
{
    if (Search(k) != NULL)
    {
        cout << "红黑树中已经有关键码值为 " << k << "的关键码,插入失败!" << endl;
        return false;
    }
    if (root == NULL)
    {
        root = new node(k, black);
        return true;
    }
    node *curr = root;
    while (curr != NULL)
    {
        if (curr->key > k)
        {
            if (curr->lchild == NULL)
            {
                curr->lchild = new node(k);
                curr->lchild->parent = curr;
                curr = curr->lchild;
                break;
            }
            else
            {
                curr = curr->lchild;
            }
        }
        else
        {
            if (curr->rchild == NULL)
            {
                curr->rchild = new node(k);
                curr->rchild->parent = curr;
                curr = curr->rchild;
                break;
            }
            else
            {
                curr = curr->rchild;
            }
        }
    }
    Insert_adjust(curr);
    return true;
}
void rd::Insert_adjust(node *curr)
{
    if (curr->color == red && curr->parent == NULL)
    {
        curr->color = black;
        return;
    }
    node *p = curr->parent;      //父节点
    if (p->color == black)
    {
        return;
    }
    else      //父节点为红色
    {
        node *g = p->parent;      //祖父节点   节点颜色为黑
        if (g->lchild == p)      //父节点为祖父节点的左孩子
        {
            node *u = g->rchild;      //叔节点
            if (u != NULL && u->color == red)      //叔节点为红色
            {
                u->color = p->color = black;
                g->color = red;
                curr = g;
                if (curr != NULL)
                {
                    Insert_adjust(curr);
                }
            }
            else      //叔节点为黑色
            {
                if (p->lchild == curr)
                {
                    p->color = black;
                    g->color = red;
                    R_rotate(g);
                    return;
                }
                else
                {
                    p = L_rotate(p);
                    p->color = black;
                    g->color = red;
                    R_rotate(g);
                    return;
                }
            }
        }
        else      //父节点为祖父节点的右孩子
        {
            node *u = g->lchild;      //叔节点
            if (u != NULL && u->color == red)
            {
                u->color = p->color = black;
                g->color = red;
                curr = g;
                if (curr != NULL)
                {
                    Insert_adjust(curr);
                }
            }
            else
            {
                if (p->rchild == curr)
                {
                    p->color = black;
                    g->color = red;
                    L_rotate(g);
                    return;
                }
                else
                {
                    p = R_rotate(p);
                    p->color = black;
                    g->color = red;
                    L_rotate(g);
                    return;
                }
            }
        }
    }
}
node* rd::Search(const int k)
{
    node *curr = root;
    while (curr != NULL)
    {
        if (curr->key > k)
        {
            curr = curr->lchild;
        }
        else if (curr->key < k)
        {
            curr = curr->rchild;
        }
        else
        {
            cout << "红黑树中存在关键码值为 " << k << " 的节点,搜索成功!" << endl;
            return curr;
        }
    }
    cout << "红黑树中不存在关键码值为 " << k << " 的节点,搜索失败!" << endl;
    return NULL;
}
node* rd::L_rotate(node *curr)
{
    node *right = curr->rchild;      
    if (curr->parent == NULL)
    {
        right->parent = NULL;
        root = right;
    }
    else
    {
        if (curr->parent->lchild == curr)
        {
            curr->parent->lchild = right;
            right->parent = curr->parent;
        }
        else
        {
            curr->parent->rchild = right;
            right->parent = curr->parent;
        }
    }
    if (right->lchild != NULL)
    {
        curr->rchild = right->lchild;
        right->lchild->parent = curr;
    }
    else
    {
        curr->rchild = NULL;
    }
    right->lchild = curr;
    curr->parent = right;
    return right;
}
node* rd::R_rotate(node *curr)
{
    node *left = curr->lchild;
    if (curr->parent == NULL)
    {
        left->parent = NULL;
        root = left;
    }
    else
    {
        if (curr->parent->lchild == curr)
        {
            curr->parent->lchild = left;
            left->parent = curr->parent;
        }
        else
        {
            curr->parent->rchild = left;
            left->parent = curr->parent;
        }
    }
    if (left->rchild != NULL)
    {
        curr->lchild = left->rchild;
        left->rchild->parent = curr;
    }
    else
    {
        curr->lchild = NULL;
    }
    left->rchild = curr;
    curr->parent = left;
    return left;
}
void rd::Remove(const int k)
{
    node *d = Search(k);      //待删除节点
    if (d == NULL)
    {
        cout << k << " 不是红黑树的关键码!" << endl;
        return;
    }
    if (d->lchild != NULL && d->rchild != NULL)
    {
        node *r = d->rchild;      //从右子树中找出最小的进行复制删除
        while (r->lchild != NULL)
        {
            r = r->lchild;
        }
        d->key = r->key;
        r->key = k;
        d = r;      //将r节点变成待删节点
    }
    Delete_adjust(d);
}
void rd::Delete_adjust(node *d)
{
    node *p = d->parent;      //待删节点的父节点
    if (d->color == red)      //待删节点为红色,直接删除
    {
        if (p->lchild == d)
        {
            p->lchild = NULL;
        }
        else
        {
            p->rchild = NULL;
        }
        delete d;
        d = NULL;
        return;
    }
    else      //待删节点为黑色 
    {
        if (p == NULL)      //待删节点为根节点
        {
            if (d->lchild != NULL)
            {
                root = d->lchild;
            }
            else if (d->rchild != NULL)
            {
                root = d->rchild;
            }
            else
            {
                delete d;
                d = NULL;
                root = NULL;
                return;
            }
            root->parent = NULL;
            root->color = black;
            delete d;
            d = NULL;
            return;
        }
        if (d->lchild != NULL)      //待删节点只有左孩子且待删节点不为根节点 且左孩子必为红色
        {
            if (p->lchild == d)      //被删节点为左子树节点
            {
                p->lchild = d->lchild;
            }
            else      //被删节点为右子树节点
            {
                p->rchild = d->lchild;
            }
            d->lchild->parent = p;
            d->lchild->color = black;
            delete d;
            d = NULL;
            return;
        }
        else if (d->rchild != NULL)      //待删节点只有右孩子且待删节点不为根节点 且右孩子必为红色
        {
            if (p->lchild == d)      //待删节点为其父节点的左孩子
            {
                p->lchild = d->rchild;
            }
            else      //待删节点为其父节点的右孩子  
            {
                p->rchild = d->rchild;
            }
            d->rchild->parent = p;
            d->rchild->color = black;
            delete d;
            d = NULL;
            return;
        }
        else      //待删节点没有左右孩子
        {
            if (p->lchild == d)      //待删节点为左子树节点
            {
                delete d;
                d = NULL;
                p->lchild = NULL;
                node *sib = p->rchild;
                if (sib->color == red)      //待删节点的兄弟节点为红色,其必有非空黑色子节点
                {
                    sib->color = black;
                    p->color = red;
                    node *sl = sib->lchild;      //待删节点兄弟节点的左孩子 为黑色
                    sib = L_rotate(p);      //sib被赋值为以p节点左旋后的新根节点
                    sl = L_rotate(sib->lchild);      //sl被赋值为以sib左孩子节点左旋后的新根节点
                    p = sl->lchild;
                    if (p->rchild != NULL)      //sl不为空,那其必为红色  实际上sl是sl的sl
                    {
                        Insert_adjust(p->rchild);
                        return;
                    }
                    else
                    {
                        return;
                    }
                }
                else      //待删节点的兄弟节点为黑色
                {
                    node *sl = sib->lchild;
                    node *sr = sib->rchild;
                    if (p->color == red)      //父节点为红色
                    {
                        if (sl == NULL && sr != NULL)
                        {
                            L_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr == NULL)
                        {
                            sl->color = black;
                            sib->color = red;
                            R_rotate(sib);
                            L_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr != NULL)
                        {
                            //sl = sl->lchild;
                            L_rotate(p);
                            if (sl == NULL)
                            {
                                return;
                            }
                            else
                            {
                                Insert_adjust(sl);
                                return;
                            }
                        }
                        else
                        {
                            p->color = black;
                            sib->color = red;
                            return;
                        }
                    }
                    else      //父节点为黑色
                    {
                        if (sl == NULL && sr != NULL)
                        {
                            sr->color = black;
                            L_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr == NULL)
                        {
                            sl->color = black;
                            R_rotate(sib);
                            L_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr != NULL)
                        {
                            sr->color = black;
                            L_rotate(p);
                            return;
                        }
                        else
                        {
                            sib->color = red;
                            DB_adjust(p);
                            return;
                        }
                    }
                }
            }
            else
            {
                delete d;
                d = NULL;
                p->rchild = NULL;
                node *sib = p->lchild;
                if (sib->color == red)      //待删节点的兄弟节点为红色,其必有非空黑色子节点
                {
                    sib->color = black;
                    p->color = red;
                    node *sr = sib->rchild;      //待删节点兄弟节点的右孩子 为黑色
                    sib = R_rotate(p);     //此时sib成为子树新的根节点
                    sr = R_rotate(sib->rchild);
                    p = sr->rchild;
                    if (p->lchild != NULL)      //sl不为空,那其必为红色
                    {
                        Insert_adjust(p->lchild);
                        return;
                    }
                    else
                    {
                        return;
                    }
                }
                else      //待删节点的兄弟节点为黑色
                {
                    node *sl = sib->lchild;
                    node *sr = sib->rchild;
                    if (p->color == red)
                    {
                        if (sr == NULL && sl != NULL)
                        {
                            R_rotate(p);
                            return;
                        }
                        else if (sr != NULL && sl == NULL)
                        {
                            sr->color = black;
                            sib->color = red;
                            L_rotate(sib);
                            R_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr != NULL)
                        {
                            //sr = sl->rchild;
                            R_rotate(p);
                            if (sr == NULL)
                            {
                                return;
                            }
                            else
                            {
                                Insert_adjust(sr);
                                return;
                            }
                        }
                        else
                        {
                            R_rotate(p);
                            return;
                        }
                    }
                    else
                    {
                        if (sr == NULL && sl != NULL)
                        {
                            sl->color = black;
                            R_rotate(p);
                            return;
                        }
                        else if (sr != NULL && sl == NULL)
                        {
                            sr->color = black;
                            L_rotate(sib);
                            R_rotate(p);
                            return;
                        }
                        else if (sl != NULL && sr != NULL)
                        {
                            sl->color = black;
                            R_rotate(p);
                            return;
                        }
                        else
                        {
                            sib->color = red;
                            DB_adjust(p);
                            return;
                        }
                    }
                }
            }
        }
    }
}
void rd::DB_adjust(node *curr)
{
    if (curr->parent == NULL)      //上溯到根节点,调整结束
    {
        return;
    }
    node *p = curr->parent;
    if (p->lchild == curr)
    {
        node *sib = p->rchild;
        node *sl = sib->lchild;
        node *sr = sib->rchild;
        if (p->color == red)      //父为红,那兄弟节点必为黑
        {
            L_rotate(p);
            Insert_adjust(sl);
        }
        else      //父为黑
        {
            if (sib->color == red)
            {
                sib->color = black;
                p->color = red;
                L_rotate(p);
            //    DB_adjust(curr);
            }
            else      //兄弟节点为黑色
            {
                if (sr->color == red)      //兄弟节点的右孩子为红色
                {
                    sr->color = black;
                    L_rotate(p);
                }
                else      //兄弟节点的右孩子为黑色
                {
                    if (sl->color == red)      //兄弟节点的左孩子为红色
                    {
                        sl->color = black;
                        R_rotate(sib);
                        L_rotate(p);
                    }
                    else      //兄弟节点左孩子为黑色
                    {
                        sib->color = red;
                        DB_adjust(p);
                    }
                }
            }
        }
    }
    else
    {
        node *sib = p->lchild;
        node *sl = sib->lchild;
        node *sr = sib->rchild;
        if (p->color == red)      //父为红,那兄弟节点必为黑
        {
            R_rotate(p);
            Insert_adjust(sr);
        }
        else      //父为黑
        {
            if (sib->color == red)
            {
                sib->color = black;
                p->color = red;
                R_rotate(p);
                //DB_adjust(curr);
            }
            else      //兄弟节点为黑色
            {
                if (sl->color == red)    //兄弟节点的左孩子为红色  
                {
                    sl->color = black;
                    R_rotate(p);
                }
                else      //兄弟节点的左孩子为黑色
                {
                    if (sr->color == red)      //兄弟节点的右孩子为红色
                    {
                        sr->color = black;
                        L_rotate(sib);
                        R_rotate(p);
                    }
                    else      //兄弟节点的左孩子为黑色
                    {
                        sib->color = red;
                        DB_adjust(p);
                    }
                }
            }
        }
    }
}

void main()
{
    //int arr[11] = { 22,55,66,44,88,11,99,33,77,100,111 };
    //int arr[11] = { 1,2,3,4,5,6,7,8,9,10,11 };
    int arr[20] = { 12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17 };
    rd tree;
    for (int i = 0; i < 20; i++)
    {
        tree.Insert(arr[i]);
    }
    node *root = tree.Get_root();
    cout << "红黑树中序遍历为:";
    tree.In_order(root);
    cout << endl;
    cout << "红黑树前序遍历为:";
    tree.Pre_order(root);
    cout << endl;
    cout << "红黑树层序遍历为:";
    tree.Level_order();
    cout << endl;
    tree.Remove(12);
    tree.Remove(1);
    tree.Remove(9);
    tree.Remove(2);
    tree.Remove(0);
    tree.Remove(11);
    tree.Remove(7);
    tree.Remove(19);
    tree.Remove(4);
    tree.Remove(15);
    tree.Remove(18);
    tree.Remove(5);
    tree.Remove(14);
    tree.Remove(13);
    tree.Remove(10);
    tree.Remove(16);
    tree.Remove(6);
    tree.Remove(3);
    tree.Remove(8);
    //tree.Remove(17);
    cout << "红黑树中序遍历为:";
    tree.IN();      //为了测试红黑树根节点是否被更替
    cout << endl;
    cout << "红黑树中序遍历为:";
    tree.In_order(root);
    cout << endl;
    root = tree.Get_root();      //红黑树的根节点已被更替
    cout << "红黑树前序遍历为:";
    tree.Pre_order(root);
    cout << endl;
    cout << "红黑树层序遍历为:";
    tree.Level_order();
    cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值