C++ 实现的红黑树的插入

正在学习红黑树,目前把插入学完理解,做个笔记

//main.cpp
//尝试自己写红黑树
#include<iostream>
#include"rbtree-class.hpp"

using namespace std;
int main(){
    RBTree<string> tree;
    /*int key=0;
    string val;
    while(key!=-1){
        cin>>key>>val;
        tree.insert(key,val);
        tree.show_LayerFirst();
    }*/
    tree.insert(12,"aaa");
    tree.insert(1,"aaa");
    tree.insert(9,"aaa");
    tree.insert(2,"aaa");
    tree.insert(0,"aaa");
    tree.insert(11,"aaa");
    tree.insert(7,"aaa");
    tree.insert(19,"aaa");
    tree.insert(4,"aaa");
    tree.insert(15,"aaa");
    tree.insert(18,"aaa");
    tree.insert(5,"aaa");
    tree.insert(14,"aaa");
    tree.insert(13,"aaa");
    tree.insert(10,"aaa");
    tree.insert(16,"aaa");
    tree.insert(6,"aaa");
    tree.insert(3,"aaa");
    tree.insert(8,"aaa");
    tree.insert(17,"aaa");
    //cout<<tree.root->right->right->left->key<<endl;
    tree.show_LayerFirst("done");
    tree.insert(3,"aaa");
    return 0;
}
//rbtree-class.hpp
#pragma once
#include<iostream>
#include<deque>
using namespace std;

template<typename T>
class RBTree{
    class node{
    public:
        int key;
        T val;
        char color;
        node  *left,*right,*father;
        node(int mkey,T mval){
            key=mkey;
            val=mval;
            left=nullptr;
            right=nullptr;
            father=nullptr;
            color='r';//默认为红色节点插入
        }
    };
    
public:
    node *root;
    RBTree(){
        root=nullptr;
    }
    ~RBTree(){
        //释放所有数据结构
    }
    
    void show_LayerFirst(const string& step){
        //层先法遍历显示
        node *p=root;
        deque<node*> queue;
        queue.push_back(p);
        cout<<step<<":";
        while(!queue.empty()){
            node *o=queue.front();
            if(o==nullptr){
                cout<<"[nil]";
                queue.pop_front();
                continue;
            }
            cout<<"["<<o->color<<"-"<<o->key<<":"<<o->val<<"]";
            queue.pop_front();
            queue.push_back(o->left);
            queue.push_back(o->right);
        }
        cout<<endl;
    }
    node* uncle(node* p){
        if(!p->father->father)return nullptr;
        //返回叔叔节点
        if(p->father->father->left==p->father){
            //叔叔节点在右边
            return p->father->father->right;
        }else{
            return p->father->father->left;
        }
    }
    void leftRotate(node* x,node* y){
        //左旋
        
        x->right=y->left;
        if(y->left!=nullptr){
            y->left->father=x;   //移交y->left的所属权,y->left父亲为x
        }
        y->father=x->father;     //X,Y同属一个父亲

        if(x==root){
            root=y;
            //root->color='b';
        }else{
            if(x==x->father->left)
                x->father->left=y;
            else
                x->father->right=y;
        }
        
        y->left=x;
        x->father=y;
        
    }
    void rightRotate(node* x,node* y){
       /* x->left=y->right;
        y->right=x;
        x->father=y;
        y->father=nullptr;
        root=y;*/
        x->left=y->right;
        if(y->right!=nullptr){
            y->right->father=x;   //移交y->left的所属权,y->left父亲为x
        }
        y->father=x->father;     //X,Y同属一个父亲

        if(x==root){
            root=y;
            //root->color='b';
        }else{
            if(x==x->father->left)
                x->father->left=y;
            else
                x->father->right=y;
        }
        y->right=x;
        x->father=y;
    }
    void adjust(node* p){//就像一个状态机,在其中转移各种状态
        
        if(!p)return;
        if(p==root){
            p->color='b';//如果根节点是红色,则染成黑色
            return;
        }
        //cout<<"l";
        //p是刚插入的新节点,在这里判断,并且旋转 
        if(p->father&&p->father->color=='b'){  //3.2情况  如果插入节点的父亲是黑色的,直接插入
            return;
        }
        //cout<<p->key;
        if(p->father&&p->father->color=='r'){  //3.4情况 如果插入节点的父亲节点同为红色
            if(uncle(p)&&uncle(p)->color=='r'){ //3.3情况  父亲和叔叔都是红色
                //cout<<3;
                p->father->color='b';
                uncle(p)->color='b';
                p->father->father->color='r';
                adjust(p->father->father);
                return;
            }
            if(uncle(p)==nullptr || uncle(p)->color=='b'){   //3.4情况 如果叔叔节点不存在或者为黑色
                //cout<<2;
                if(p==p->father->left){
                    if(!p->father->father)return;
                    if(p->father==p->father->father->left){ //3.4.1  ll情况
                        
                        char color=p->father->color;
                        p->father->color=p->father->father->color;
                        p->father->father->color=color;                 //交换颜色
                        show_LayerFirst("LL");
                        rightRotate(p->father->father,p->father);       //右旋
                    }else{//3.4.4  lr情况
                        node* father=p->father;
                        rightRotate(father,p);                       //直接右旋
                        show_LayerFirst("LR");
                        adjust(father);
                        
                    }
                    return;
                }
                if(p==p->father->right){
                    if(!p->father->father)return;
                    if(p->father==p->father->father->left){ //3.4.2  rl情况
                        node* father=p->father;
                        leftRotate(father,p);
                        show_LayerFirst("RL");
                        adjust(father);
                    }else{//3.4.3  rr情况
                        char color=p->father->color;
                        p->father->color=p->father->father->color;
                        p->father->father->color=color;                 //交换颜色
                        show_LayerFirst("RR\t\t");
                        leftRotate(p->father->father,p->father);       //左旋
                        show_LayerFirst("RR左旋后\t");
                    }
                    return;
                }
            }
        }

    }
    void insert(int key,T val){
        cout<<"insert:"<<key<<":"<<val<<endl;
        if(root==nullptr){
            //根节点一定是黑色
            root=new node(key,val);
            root->color='b';
        }
        else{
            node *p=root;
            while(1){     //找到合适的位置,开始插入
                if(p->key==key){    //如果键相同就更新值即可
                    p->val=val;
                    return;
                }
                if(key>p->key){     //大的在右子树,小的在左子树
                    if(p->right==nullptr){
                        
                        p->right=new node(key,val);
                        p->right->father=p;         //设置新节点的父亲
                        //show_LayerFirst("调整前r");
                        adjust(p->right);           //插入完成后,用一个函数来调整
                        return;
                    }else{
                        p=p->right;
                    }  
                }else{
                    if(p->left==nullptr){
                        
                        p->left=new node(key,val);
                        p->left->father=p;
                        //show_LayerFirst("调整前l");
                        adjust(p->left);
                        return;
                    }else{
                        p=p->left;
                    }  
                }
            }
        }
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值