RBTree(Insert & Delete)

  这个红黑树想了很久,特别在做删除时候,搞不懂《算法导论》里面那个x是什么东西,最后想了很久,最终才知道那个x原来是删除后的节点的候补节点,y是被删除的节点,我在做这个程序的时候可能跟《算法导论》的处理有点不同,它里面的NULL节点与我的处理好象不一样(反正我看得不是很懂) ,我对于那个NULL节点,是在deletefixup里面new两个新的节点,不断的通过检测是否为空,来将其赋值,然后在每次循环后就将父节点指向这两个plNull,prNull的指针置空!这样就可以很好的保证如果某一个节点为空时的处理(今晚想出来的,头脑笨,没办法),做这个红黑树比较重要的一个是旋转,关于左旋和右旋,很多都有介绍,我就不提了,然后另外一个就是如何着色,特别对于删除的情况比较多,所以要仔细分析才可以很好的写出来!对于我这个红黑树,我没用检查很仔细,可能还有错误的地方,不过我想理解好了思想,大概的细节问题都差不多解决就ok了!还有更多的算法和数据结构学阿!明天继续(如果毕业设计不急的话,呵)

eg:

success to insert..
success to insert..
success to insert..
success to insert..
A same element exist..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
success to insert..
item: 0  red
item: 1  black
item: 2  black
item: 4  black
item: 5  red
item: 6  red
item: 7  black
item: 9  black
item: 11  black
item: 12  red
item: 13  black
item: 14  black
item: 15  red
item: 17  black
Press any key to continue

 

程序比较长:头文件

#include<iostream>
#include<deque>
using namespace std;

class RBTree;
enum Color{red = 0,black = 1};

class RBNode
{
 friend class RBTree;
 private:
  RBNode *left;
  RBNode *right;
  RBNode *parent;
  Color color;
  int item;
 public:
  RBNode(int x);
  ~RBNode(){}
};

class RBTree
{
 private:
  RBNode *root;
  RBNode *current;
  void LeftRotate(RBNode *y,RBNode *x);
  void RightRotate(RBNode *y,RBNode *x);
  bool Insert(RBNode *x);
  void DeleteFixup(RBNode *x);
 public:
  RBTree(RBNode *R);
  ~RBTree();
  void DeleteRBTree(RBNode *pDT);
  void Display();
  void Rotate();
  void InsertNode(RBNode *x);
  RBNode *Root();
  void DeleteNode(RBNode *pDN);
//  bool Delete(int x);
   void Delete(int data);
  void MidOrder(RBNode *PO);
};

RBNode::RBNode(int x)
{
 color = red;
 item = x;
 left = NULL;
 right = NULL;
 parent = NULL;
}

RBNode* RBTree::Root()
{
 return root;
}

void RBTree::MidOrder(RBNode *PO)
{
 if(PO != NULL)
 {
  MidOrder(PO->left);
  cout<<"item: "<<PO->item;
 
  if(PO->color == red)
   cout<<"  red"<<endl;
  else
   cout<<"  black"<<endl;
     MidOrder(PO->right);
 }
}
 
RBTree::RBTree(RBNode *R)
{
 if(R != NULL)
 {
  R->color = black;
  this->root = R;
  this->current = R;
 }
 else
 {
  cout<<"Error by construct the rbtree..."<<endl;
 }
}

RBTree::~RBTree()
{
 if(root != NULL)
 DeleteRBTree(root);
 else
  cout<<"Error by free the rbtree.."<<endl;
}

void RBTree::DeleteRBTree(RBNode *pDT)
{
 if(pDT != NULL)
 {
  DeleteRBTree(pDT->left);
  DeleteRBTree(pDT->right);
  delete pDT;
 }
}

void RBTree::LeftRotate(RBNode *y,RBNode *x)
{
 if(y == root)
 {
  root = x;
  x->parent = NULL;
 }
 else
 {
  x->parent = y->parent;
 }

 if(x->left != NULL)
 {
  y->right = x->left;
  x->left->parent = y;
  x->left = y;
  if((x != root)&&(y->parent->left == y))
   y->parent->left = x;
  else if((x != root)&&(y->parent->right == y)) 
   y->parent->right = x;
  y->parent = x;
 }
 else
 {
  y->right = NULL;
  x->left = y;
  if((y != root)&&(y->parent->left == y))
   y->parent->left = x;
  else 
   y->parent->right = x;
  y->parent = x;
 }
}

void RBTree::RightRotate(RBNode *y,RBNode *x)
{
 if(y == root)
 {
  root = x;
  x->parent = NULL;
 }
 else
 {
  x->parent = y->parent;
 }

 if(x->right != NULL)
 {
  y->left = x->right;
  x->right->parent = y;
  x->right = y;
  if((x != root)&&(y->parent->left == y))
   y->parent->left = x;
  else if((x != root)&&(y->parent->right == y)) 
   y->parent->right = x;
  y->parent = x;
 }
 else
 {
  y->left = NULL;
  x->right = y;
  if((x != root)&&(y->parent->left == y))
   y->parent->left = x;
  else if((x != root)&&(y->parent->right == y)) 
   y->parent->right = x;
  y->parent = x;
 }
}

bool RBTree::Insert(RBNode *x)
{
 bool test = false;
 while(!test)
 {
  if(x->item == current->item)
  {
   test = true;
   cout<<"A same element exist.."<<endl;
   delete x;
   return false;
  }
  else if(x->item>current->item)
  {
   if(current->right == NULL)
   {
    current->right = x;
    x->parent = current;
    current = current->right;
    cout<<"success to insert.."<<endl;
    test = true;
   }
   else
   {
    current = current->right;
   }
  }
  else if(x->item<current->item)
  {
   if(current->left == NULL)
   {
    current->left = x;
    x->parent = current;
    current = current->left;
    cout<<"success to insert.."<<endl;
    test = true;
   }
   else
   {
    current = current->left;
   }
  }
 }
 return true;
}

void RBTree::InsertNode(RBNode *x)
{
 current = root;
 RBNode *x_uncle = NULL;
 if(this->Insert(x))
 {
  while((x != root)&&(x->parent->color == red))
  {
   if(x->parent == x->parent->parent->left)  //two if to set up the uncle of x
   {
    if(x->parent->parent->right != NULL)
    {
     x_uncle = x->parent->parent->right;
    }

    if((x_uncle != NULL)&&(x_uncle->color == red))     //if uncle is red->x,x_uncle up only
    {
     x->parent->color = black;
     x_uncle->color = black;
     x->parent->parent->color = red;
     x = x->parent->parent;
    }
    else          //if uncle is black->2 situation
    {
     if((x->parent->right != NULL)&&(x == x->parent->right))   
     {    //1 x is right child only rotate
      x = x->parent;
      this->LeftRotate(x,x->right);
     }
     else if((x->parent->left != NULL)&&(x == x->parent->left)) 
     {    //2 x is left child need to change color and rotate
      x->parent->parent->color = red;
      x->parent->color = black;
      this->RightRotate(x->parent->parent,x->parent);
     }
    }
   }
   else if(x->parent == x->parent->parent->right)
   {
    if(x->parent->parent->left != NULL)
    {
     x_uncle = x->parent->parent->left;
    }

    if((x_uncle != NULL)&&(x_uncle->color == red))     //if uncle is red->x,x_uncle up only
    {
     x->parent->color = black;
     x_uncle->color = black;
     x->parent->parent->color = red;
     x = x->parent->parent;
    }
    else          //if uncle is black->2 situation
    {
     if((x->parent->left != NULL)&&(x == x->parent->left))   
     {    //1 x is left child only rotate
      x = x->parent;
      this->RightRotate(x,x->left);
     }
     else if((x->parent->right != NULL)&&(x == x->parent->right)) 
     {    //2 x is right child need to change color and rotate
      x->parent->parent->color = red;
      x->parent->color = black;
      this->LeftRotate(x->parent->parent,x->parent);
     }
    }
   }
  }
  root->color = black;
 }
}

void RBTree::Delete(int data)
{
   RBNode *x, *y;
   bool xNull = false;
   current = root;
   while((current != NULL)&&(current->item != data))
   {
    if(data>current->item)
    {
     current = current->right;
    }
    else if(data<current->item)
    {
     current = current->left;
    }
   }//while

   if(current == NULL)
   {
    cout<<"can't find the element.."<<endl;
   }//can't find
   else
   {
    if((current->left == NULL)&&(current->right == NULL))
    {
     y = current;
     x = NULL;   
    }
    else if((current->left != NULL)&&(current->right == NULL))
    {
     y = current;
     x = current->left;    
    }
    else if((current->left == NULL)&&(current->right != NULL))
    {
     y = current;
     x = current->right;    
    }
    else if((current->left != NULL)&&(current->right != NULL))
    {
     y = current->right;
     while(y->left != NULL)
     {
      y = y->left;
     }
   x = y->right;
      current->item = y->item;
    }
   if(y->color == black)
   {
    if(x == NULL)
    {
     x = y;
     xNull = true;
    }
    this->DeleteFixup(x);
   }

   if(xNull)
    x = NULL;

   if(y == root)
   {
    cout<<"The tree root be deleted.."<<endl;
  if(x == NULL)
   root = NULL;
  else
   root = x;
   }
   else
   {
    if(y->parent->left == y)
    {
     y->parent->left = x;
     if(x != NULL)
      x->parent = y->parent;
    }
    else if(y->parent->right == y)
    {
     y->parent->right = x;
     if(x != NULL)
      x->parent = y->parent;
    }
   }
  delete y;
 }
}


void RBTree::DeleteFixup(RBNode *x)
{
 RBNode *w;
 RBNode *plNull = new RBNode(0);
 plNull->color = black;
 RBNode *prNull = new RBNode(0);
 prNull->color = black;

 while((x != root)&&(x->color == black))
 {
  if(x->parent->left == x)                  //  x = left(px)
  { //situation 1
   w = x->parent->right;
   
   if(w->left == NULL)
   {
    w->left = plNull;
    plNull->parent = w;
   }
   if(w->right == NULL)
   {
    w->right = prNull;
    prNull->parent = w;
   }
    
   if(w->color == red)
   {
    w->color = black;
    w->parent->color = red;
    this->LeftRotate(w->parent,w);
   }
   else
   {
    if((w->left->color == black)&&(w->right->color == black))
    {
     w->color = red;
     x = x->parent;
    }
    else if((w->left->color == red)&&(w->right->color == black))
    {
     w->left->color = black;
     w->color = red;
     this->RightRotate(w,w->left);
    }
    else if(w->right->color == red)
    {
     w->color = w->parent->color;
     w->parent->color = black;
     w->right->color = black;
     this->LeftRotate(w->parent,w);
     x = root;
    }
   }
  }
  else if(x->parent->right == x)                  //  x = left(px)
  { //situation 1
   w = x->parent->left;

   if(w->left == NULL)
    w->left = plNull;
   if(w->right == NULL)
    w->right = prNull;

   if(w->color == red)
   {
    w->color = black;
    w->parent->color = red;
    this->RightRotate(w->parent,w);
   }
   else
   {
    if((w->left->color == black)&&(w->right->color == black))
    {
     w->color = red;
     x = x->parent;
    }
    else if((w->right->color == red)&&(w->right->color == black))
    {
     w->right->color = black;
     w->color = red;
     this->LeftRotate(w,w->left);
    }
    else if(w->left->color == red)
    {
     w->color = w->parent->color;
     w->parent->color = black;
     w->left->color = black;
     this->RightRotate(w->parent,w);
     x = root;
    }
   }
  }
  
  if(plNull->parent != NULL)
  {
   if(plNull->parent->left == plNull)
    plNull->parent->left = NULL;
   else if(plNull->parent->right == plNull)
    plNull->parent->right = NULL;

   plNull->parent = NULL;
  }
  if(prNull->parent != NULL)
  {
   if(prNull->parent->left == prNull)
    prNull->parent->left = NULL;
   else if(prNull->parent->right == prNull)
    prNull->parent->right = NULL;
   
   prNull->parent = NULL;
  }
 }
 x->color = black;
 delete plNull;
 delete prNull;

}

 

测试文件:main()

#include"RBTree.h"

void main()
{
 RBNode *R = new RBNode(11);
 RBTree rbtree(R);
 RBNode *Node1 = new RBNode(8);
 rbtree.InsertNode(Node1);
 RBNode *Node2 = new RBNode(2);
 rbtree.InsertNode(Node2);
 RBNode *Node3 = new RBNode(14);
 rbtree.InsertNode(Node3);
 RBNode *Node4 = new RBNode(7);
 rbtree.InsertNode(Node4);
 RBNode *Node5 = new RBNode(8);
 rbtree.InsertNode(Node5);
 RBNode *Node6 = new RBNode(1);
 rbtree.InsertNode(Node6);
 RBNode *Node7 = new RBNode(5);
 rbtree.InsertNode(Node7);
 RBNode *Node8 = new RBNode(4);
 rbtree.InsertNode(Node8);
 RBNode *Node9 = new RBNode(9);
 rbtree.InsertNode(Node9);
 RBNode *Node10 = new RBNode(13);
 rbtree.InsertNode(Node10);
 RBNode *Node11 = new RBNode(6);
 rbtree.InsertNode(Node11);
 RBNode *Node12 = new RBNode(0);
 rbtree.InsertNode(Node12);
 RBNode *Node13 = new RBNode(17);
 rbtree.InsertNode(Node13);
 RBNode *Node14 = new RBNode(15);
 rbtree.InsertNode(Node14);
 RBNode *Node15 = new RBNode(12);
 rbtree.InsertNode(Node15);/**/
 rbtree.Delete(8);
 rbtree.MidOrder(rbtree.Root());
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值