如题,,红黑树实现前头学习了容器的使用,发现了之前写的没加卫星数据的问题。改进了
//红黑树,有卫星数据
#include <iostream>
using namespace std;
enum Color{
red,black
};
template <class Key ,class Type>
struct node{
Key key;
Type data;
Color color;//颜色,
node<Key,Type> *left;
node<Key,Type> *right;
node<Key,Type> *parent;
};
template <class Key ,class Type>
class rbtree_class{
private:
node<Key,Type> *root;
node<Key,Type> *nil;
int size;
public:
rbtree_class();
void NodeCpy(node<Key,Type>* &,node<Key,Type>* &,node<Key,Type>* & );
rbtree_class(rbtree_class<Key,Type> &);
void NodeDel(node<Key,Type> * );
~rbtree_class();
//首先定义左旋转与右旋转 左旋把节点的右孩子(存在)转到它位置,自己变成其左孩子,右旋相反,详细参看书吧,比较麻烦,后面分析也要用到这两个操作
void LeftRotate(node<Key,Type> *);
void RightRotate(node<Key,Type> *);
//然后定义fixup维持红黑树的性质
void RbInsertFixup(node<Key,Type> * &);
bool Insert(const Key &,const Type &);
void Show(node<Key,Type> *);
void ShowAll();//输出所有元素(按续)与颜色
node<Key,Type> * MinNode(node<Key,Type> *);//从某节点开始向下找最小Key值的节点
node<Key,Type> * Min();
node<Key,Type> * Replace(node<Key,Type> * des,node<Key,Type> * src);//src带上自己的子树替代des,父母节点相关的替代,
node<Key,Type> * SearchNode(node<Key,Type> *,const Key &);
node<Key,Type> * Search(const Key &);//搜寻key,返回这个key的节点的指针 不存在返回nil
void RbDeleteFixup(node<Key,Type> * &);
bool Delete(const Key&);
};
//主函数
int main(){
rbtree_class<int,char> test;
char c[10]="abcdefghi";
test.Insert(11,c[6]);
/* test.Insert(2,c[1]);
test.Insert(1,c[0]);
test.Insert(7,c[4]);
test.Insert(14,c[7]);
test.Insert(15,c[8]);
test.Insert(5,c[3]);
test.Insert(8,c[5]);
test.Insert(4,c[2]);
test.ShowAll();
node<int,char> * p;
p = test.Search(2);
cout<<"search="<<p->data<<endl;
p = test.Min();
cout<<"min="<<p->data<<endl;*/
test.Delete(11);
cout<<"after delete"<<endl;
test.ShowAll();
return 0;
}
//主函数
template <class Key, class Type>
rbtree_class<Key,Type>::rbtree_class(){
nil = new node<Key,Type>;
nil->color = black;
root = nil;
size = 0;
cout<<"default"<<endl;
}
template <class Key, class Type>
void rbtree_class<Key,Type>::NodeCpy(node<Key,Type>* & des,node<Key,Type>* & src,node<Key,Type>* & src_nil){
node<Key,Type> *tmp;
if(src->left!=src_nil){//拷贝src的左孩子
// cout<<"src,left"<<endl;
tmp = new node<Key,Type>;
tmp->key = src->left->key;//这里可以再用一个临时指针,指向src的下一层
tmp->data = src->left->data;
tmp->color = src->left->color;
tmp->left = nil;
tmp->right = nil;
tmp->parent = des;
des->left = tmp;//在des上加入了左孩子节点
size++;
NodeCpy(des->left,src->left,src_nil);
}else{
des->left = nil;
}
if(src->right!=src_nil){
// cout<<"src,right"<<endl;
tmp = new node<Key,Type>;
tmp->value = src->right->value;
tmp->left = nil;
tmp->right = nil;
tmp->parent = des;
des->right = tmp;//在des上加入了右孩子节点
size++;
NodeCpy(des->right,src->right,src_nil);
}else{
des->right = nil;
}
return;
}
template <class Key, class Type>
rbtree_class<Key,Type>::rbtree_class(rbtree_class<Key,Type> & arg){
nil = new node<Key,Type>;
nil->color = black;
root = nil;
if(arg->root == arg->nil) return;
root = new node<Key,Type>;
root->key = arg.root->key;
root->data = arg.root->data;
root->color = arg.root->color;
root->left = nil;
root->right = nil;
root->parent = nil;
size = arg.size;
NodeCpy(root,arg.root,arg.nil);
}
template <class Key,class Type>
void rbtree_class<Key,Type>::NodeDel(node<Key,Type> * arg){
if(arg==nil) return;
else{
NodeDel(arg->left);
NodeDel(arg->right);
delete arg;
}
return ;
}
template <class Key,class Type>
rbtree_class<Key,Type>::~rbtree_class(){
if(size!=0){
NodeDel(root->left);
NodeDel(root->right);
delete root;
delete nil;
}
}
template <class Key,class Type>
void rbtree_class<Key,Type>::LeftRotate(node<Key,Type> * arg){
node<Key,Type> *tmp;
tmp = arg->right;
arg->right = tmp->left;
if(tmp->left!=nil) tmp->left->parent = arg;
tmp->parent = arg->parent;
if(arg->parent==nil) root = tmp;
else if(arg == arg->parent->left) arg->parent->left = tmp;
else arg->parent->right = tmp;
tmp->left = arg;
arg->parent = tmp;
cout<<"left rotate"<<endl;
return;
}
template <class Key,class Type>
void rbtree_class<Key,Type>::RightRotate(node<Key,Type> * arg){
node<Key,Type> *tmp;
tmp = arg->left;
arg->left = tmp->right;
if(tmp->right!=nil) tmp->right->parent = arg;
tmp->parent = arg->parent;
if(arg->parent==nil) root = tmp;
else if(arg == arg->parent->left) arg->parent->left = tmp;
else arg->parent->right = tmp;
tmp->right = arg;
arg->parent = tmp;
cout<<"right rotate"<<endl;
return;
}
template <class Key,class Type>
void rbtree_class<Key,Type>::RbInsertFixup(node<Key,Type> * & arg){
node<Key,Type> * tmp;
while(arg->parent->color == red){
if(arg->parent == arg->parent->parent->left){
tmp = arg->parent->parent->right;
if(tmp->color==red){ //情况1
cout<<"case1"<<endl;
arg->parent->color = black;
tmp->color = black;
arg->parent->parent->color = red;
arg = arg->parent->parent;
}
else{
if(arg == arg->parent->right){
cout<<"case2"<<endl;//情况2变换到情况3,
arg = arg->parent;
LeftRotate(arg);
}
cout<<"case3"<<endl;
arg->parent->color = black;//情况3
arg->parent->parent->color = red;
RightRotate(arg->parent->parent);
}
}//下面对称的456情况
else if(arg->parent == arg->parent->parent->right){
tmp = arg->parent->parent->left;
if(tmp->color==red){
cout<<"case4"<<endl;
arg->parent->color = black;
tmp->color = black;
arg->parent->parent->color = red;
arg = arg->parent->parent;
}
else{
if(arg == arg->parent->left){
cout<<"case5"<<endl;
arg = arg->parent;
RightRotate(arg);
}
cout<<"case6"<<endl;
arg->parent->color = black;
arg->parent->parent->color = red;
LeftRotate(arg->parent->parent);
}
}
}
root->color = black;
return;
}
template <class Key,class Type>
bool rbtree_class<Key,Type>::Insert(const Key & key,const Type & data){
node<Key,Type> *tmp;//用来遍历向下的指针 ,直到nil,就在该位置插入数据
node<Key,Type> *tmp_p;//用到指到当前节点的指针
tmp = root;
tmp_p = nil;
// cout<<"tmp,tmp_p ojbk"<<endl;
while(tmp!=nil){
tmp_p = tmp;
if(key>tmp->key) tmp = tmp->right;
else if(key<tmp->key) tmp = tmp->left;
else if(key==tmp->key) return false;
} //一直搜索到了二叉树的最下层节点,最后tmp指到了nil,tmp_p是这个NULL位置的父节点
// cout<<"find place"<<endl;
tmp = new node<Key,Type>;
tmp->key = key;
tmp->data = data;
tmp->color = red;
tmp->left = nil;
tmp->right = nil;
tmp->parent = tmp_p;
// cout<<"created success"<<endl;
size++;
if(tmp_p==nil){
root = tmp;
cout<<"insert root"<<endl;
RbInsertFixup(tmp);
return true;
}//无元素
else if(tmp_p->key>key){
tmp_p->left = tmp;
cout<<"insert left"<<endl;
RbInsertFixup(tmp);
return true;
}
else if(tmp_p->key<key){
tmp_p->right = tmp;
cout<<"insert right"<<endl;
RbInsertFixup(tmp);
return true;
}
else{
cout<<"logic failed"<<endl;
return false;
}
}
template <class Key,class Type>
void rbtree_class<Key,Type>::Show(node<Key,Type> * arg){
if(arg!=nil){
Show(arg->left);
cout<<"key="<<arg->key;
if(arg->color==black)
cout<<" color=black";
else
cout<<" color=red";
cout<<" data="<<arg->data<<endl;
Show(arg->right);
}
else return;
}
template <class Key,class Type>
void rbtree_class<Key,Type>::ShowAll(){
node<Key,Type> *tmp;
tmp = root;
cout<<"size="<<size<<endl;
if(root!=nil){
cout<<"into show"<<endl;
Show(tmp);
}
return;
}
template <class Key,class Type>
node<Key,Type> * rbtree_class<Key,Type>::MinNode(node<Key,Type> *arg){
node<Key,Type> *tmp = arg;
if(tmp==nil) return tmp;
while(tmp->left!=nil){
tmp = tmp->left;
}
return tmp;
}
template <class Key,class Type>
node<Key,Type> * rbtree_class<Key,Type>::Min(){
return MinNode(root);
}
template <class Key,class Type>
node<Key,Type> * rbtree_class<Key,Type>::Replace(node<Key,Type> * des,node<Key,Type> * src){
if(des->parent==nil) root = src;
else if(des->parent->left==des){
des->parent->left = src;
}else if(des->parent->right==des){
des->parent->right = src;
}
if(src!=nil) src->parent = des->parent;
return des;
}
template <class Key,class Type>
node<Key,Type> * rbtree_class<Key,Type>::SearchNode(node<Key,Type> * p,const Key & key){
if(p==nil||p->key==key) return p;
if(p->key>key) return SearchNode(p->left,key);
if(p->key<key) return SearchNode(p->right,key);
}
template <class Key,class Type>
node<Key,Type> * rbtree_class<Key,Type>::Search(const Key & key){
node<Key,Type> *tmp=root;
while(tmp!=nil){
if(tmp->key==key) return tmp;
else if(tmp->key>key) tmp = tmp->left;
else tmp = tmp->right;
}
return tmp;
}
template <class Key,class Type>
void rbtree_class<Key,Type>::RbDeleteFixup(node<Key,Type> * &arg){
node<Key,Type> *tmp;
cout<<"into delete fix"<<endl;
while(arg!=root && arg->color==black){
if(arg==arg->parent->left){
tmp = arg->parent->right;
if(tmp->color==red){
tmp->color=black;
arg->parent->color = red;
LeftRotate(arg->parent);
tmp = arg->parent->right;
cout<<"delete fix case1"<<endl;
}
if(tmp->left->color==black && tmp->right->color==black){
tmp->color = red;
arg = arg->parent;
cout<<"delete fix case2"<<endl;
}
else{
if(tmp->right->color==black){
tmp->left->color = black;
tmp->color = red;
RightRotate(tmp);
tmp = arg->parent->right;
cout<<"delete fix case3"<<endl;
}
tmp->color = arg->parent->color;
arg->parent->color = black;
tmp->right->color = black;
LeftRotate(arg->parent);
arg = root;
cout<<"delete fix case4"<<endl;
}
}
else{
tmp = arg->parent->left;
if(tmp->color==red){
tmp->color=black;
arg->parent->color = red;
RightRotate(arg->parent);
tmp = arg->parent->left;
cout<<"delete fix case5"<<endl;
}
if(tmp->right->color==black && tmp->left->color==black){
tmp->color = red;
arg = arg->parent;
cout<<"delete fix case6"<<endl;
}
else{
if(tmp->left->color==black){
tmp->right->color = black;
tmp->color = red;
LeftRotate(tmp);
tmp = arg->parent->left;
cout<<"delete fix case7"<<endl;
}
tmp->color = arg->parent->color;
arg->parent->color = black;
tmp->left->color = black;
RightRotate(arg->parent);
arg = root;
cout<<"delete fix case8"<<endl;
}
}
}
arg->color = black;
}
template <class Key,class Type>
bool rbtree_class<Key,Type>::Delete(const Key& key){
node<Key,Type> *tmp;
node<Key,Type> *target;
node<Key,Type> *x;
target = Search(key);
if(target==nil) return false;
cout<<"delete,find="<<target->data<<endl;
tmp = target;
Color tmp_ori_color = tmp->color;
if(target->left==nil){
x = target->right;
Replace(target,target->right);
delete target;
}
else if(target->right==nil){
x = target->left;
Replace(target,target->left);
delete target;
}
else{
tmp = MinNode(target->right);
cout<<"find minnode="<<tmp->data<<endl;
tmp_ori_color = tmp->color;
x = tmp->right;
if(tmp->parent==target) x->parent = tmp;
else{
Replace(tmp,tmp->right);
tmp->right = target->right;
tmp->right->parent = tmp;
}
Replace(target,tmp);
delete target;
tmp->left = target->left;
tmp->left->parent = tmp;
tmp->color = target->color;
}
size--;
if(size==0){
cout<<"delete make 0"<<endl;
root = nil;
}
// ShowAll();
if(tmp_ori_color==black&&x!=nil){
cout<<"delete fix"<<endl;
RbDeleteFixup(x);
}
return true;
}