正在学习红黑树,目前把插入学完理解,做个笔记
//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;
}
}
}
}
}
};