introduction to algorithms 菜鸟笔记 rbtree(红黑树)

来源:互联网 发布:知礼节 编辑:程序博客网 时间:2024/04/29 13:22

//author:yydrewdrew

#include <iostream>
using namespace std;

 

 

template <class T>
struct RBTreeNode
{
 T data;
 RBTreeNode *parent;
 RBTreeNode *left;
 RBTreeNode *right;
 enum Color{R,B};
 Color color;
};

 


template <class T>
class RBTree
{
public:
 void TreeWalk()const;
 RBTreeNode<T> *Insert(const T &t);
 RBTreeNode<T> *Delete(const T &t);
 RBTreeNode<T> *Serach(const T &t)const;
 RBTreeNode<T> *Predecesor(const T &t)const;
 RBTreeNode<T> *Successor(const T &t)const;
 RBTreeNode<T> *Min()const;
 RBTreeNode<T> *Max()const;
 void Clear();
 void Swap(RBTree<T> &obj);
public:
 RBTree():root(NULL),NIL(new(RBTreeNode<T>))
 {
  NIL->data = 0;
  NIL->left = NULL;
  NIL->right = NULL;
  NIL->color = RBTreeNode<T>::B;
 }
 RBTree<T> &operator = (const RBTree<T> &obj);
 RBTree<T>(const RBTree<T> &obj);
 virtual ~RBTree();
private:
 RBTree(RBTreeNode<T> *r,RBTreeNode<T> *nil):root(r),NIL(nil){}
 void LeftRotate(RBTreeNode<T> *const p);
 void LeftRotate(const T &t);
 void RightRotate(RBTreeNode<T> *const p);
 void RightRotate(const T &t);
 void RBInsertFixup(RBTreeNode<T> *p);
 void RBDeleteFixup(RBTreeNode<T> *p);
 void Clean()
 {
  root = NULL;
  NIL = NULL;
 }
 void Destory(RBTreeNode<T> *p);
 void Scan(RBTreeNode<T> *root)const;
 void Copy(RBTreeNode<T> *p,const RBTree<T> &obj);
private:
 RBTreeNode<T> *root;
 RBTreeNode<T> *NIL;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::Swap(RBTree<T> &obj)
{
 std::swap(root,obj.root);
 std::swap(NIL,obj.NIL);
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTree<T> &RBTree<T>::operator = (const RBTree<T> &obj)
{
 if (this != &obj)
 {
  Swap(RBTree<T>(obj));
 }
 return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::Copy(RBTreeNode<T> *p,const RBTree<T> &obj)
{
 if (p != obj.NIL)
 {
  Copy(p->left,obj);
  Insert(p->data);
  Copy(p->right,obj);
 }
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTree<T>::RBTree(const RBTree<T> &obj)
{
 root = NULL;
 NIL = new RBTreeNode<T>;
 NIL->data = 0;
 NIL->left = NULL;
 NIL->right = NULL;
 NIL->color = RBTreeNode<T>::B;
 Copy(obj.root,obj);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::Scan(RBTreeNode<T> *root)const
{
 if (root == NULL || root == NIL)
 {
  return;
 }
 Scan(root->left);
 cout<<root->data<<endl;
 Scan(root->right);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::TreeWalk()const
{
 Scan(root);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Min()const
{
 if (root == NULL)
 {
  return NULL;
 }
 RBTreeNode<T> *p = root;
 RBTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->left;
 }
 return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Max()const
{
 if (root == NULL)
 {
  return NULL;
 }
 RBTreeNode<T> *p = root;
 RBTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->right;
 }
 return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Serach(const T &t)const
{
 if (root == NULL)
 {
  return NULL;
 }
 RBTreeNode<T> *p = root;
 while (p != NIL)
 {
  if (t > p->data)
  {
   p = p->right;
  }
  else if (t < p->data)
  {
   p = p->left;
  }
  else
  {
   return p;
  }
 }
 return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Successor(const T &t)const
{
 RBTreeNode<T> *p = Serach(t);
 if (p->right != NIL)
 {
  RBTree treetem(p->right,NIL);
  p = treetem.Min();
  treetem.Clean();
  return p;
 }
 RBTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->right)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Predecesor(const T &t)const
{
 RBTreeNode<T> *p = Serach(t);
 if (p->left != NIL)
 {
  RBTree<T> treetem(p->left,NIL);
  p = treetem.Max();
  treetem.Clean();
  return p;
 }
 RBTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->left)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::LeftRotate(RBTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if(p->right == NIL)
 {
  return;
 }
 RBTreeNode<T> *p2 = p->right;
 p2->parent = p->parent;
 if (p->parent != NIL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 if (p2->left != NIL)
 {
  p2->left->parent = p;
 }
 p->right = p2->left;
 p2->left = p;
 p->parent = p2;
 return;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::LeftRotate(const T &t)
{
 RBTreeNode<T> *p = Serach(t);
 LeftRotate(p);
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::RightRotate(RBTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if (p->left == NIL)
 {
  return;
 }
 RBTreeNode<T> *p2 = p->left;
 if (p2->right != NIL)
 {
  p2->right->parent = p;
 }
 p->left = p2->right;
 p2->parent = p->parent;
 if (p->parent != NIL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 p->parent = p2;
 p2->right = p;
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::RightRotate(const T &t)
{
 RBTreeNode<T> *p = Serach(t);
 RightRotate(p);
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Insert(const T &t)
{
 RBTreeNode<T> *p = root;
 RBTreeNode<T> *p2 = NULL;
 while (p != NIL && p != NULL)
 {
  p2 = p;
  if (t > p->data)
  {
   p = p->right;
  }
  else
  {
   p = p->left;
  }
 }
 RBTreeNode<T> *ptem = new RBTreeNode<T>;
 ptem->data = t;
 ptem->left = NIL;
 ptem->right = NIL;
 if (p == NULL)
 {
  root = ptem;
  root->color = RBTreeNode<T>::B;
  root->parent = NIL;
 }
 else
 {
  if (t > p2->data)
  {
   p2->right = ptem;
   ptem->color = RBTreeNode<T>::R;
   ptem->parent = p2;
  }
  else
  {
   p2->left = ptem;
   ptem->color = RBTreeNode<T>::R;
   ptem->parent = p2;
  }
 }
 RBInsertFixup(ptem);
 return ptem;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::RBInsertFixup(RBTreeNode<T> *p)
{
 while (p->parent->color == RBTreeNode<T>::R)
 {
  if (p->parent == p->parent->parent->left)
  {
   RBTreeNode<T> *y = p->parent->parent->right;
   if (y->color == RBTreeNode<T>::R)
   {
    p->color = RBTreeNode<T>::B;
    y->color = RBTreeNode<T>::B;
    p->parent->parent->color = RBTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->right)
   {
    p = p->parent;
    LeftRotate(p);
   }
   p->parent->color = RBTreeNode<T>::B;
   p->parent->parent->color = RBTreeNode<T>::R;
   RightRotate(p);
  }
  else
  {
   RBTreeNode<T> *y = p->parent->parent->left;
   if (y->color == RBTreeNode<T>::R)
   {
    p->color = RBTreeNode<T>::B;
    y->color = RBTreeNode<T>::B;
    p->parent->parent->color = RBTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->left)
   {
    p = p->parent;
    RightRotate(p);
   }
   p->parent->color = RBTreeNode<T>::B;
   p->parent->parent->color = RBTreeNode<T>::R;
   LeftRotate(p);
  }
 }
 root->color = RBTreeNode<T>::B;
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTreeNode<T> *RBTree<T>::Delete(const T &t)
{
 RBTreeNode<T> *p = Serach(t);
 RBTreeNode<T> *p2 = p;
 if (p->left != NIL && p->right !=NIL)
 {
  p2 = Successor(t);
  if (p2->parent == NIL)
  {
   root = p2->right;
   p2->right->parent = root;
  }
  else
  {
   if (p2 == p2->parent->left)
   {
    p2->parent->left = p2->right;
   }
   else
   {
    p2->parent->right = p2->right;
   }
  }
  p2->right->parent = p2->parent;
  swap(p->data,p2->data); 
  p = p2;  
  p2 = p2->right;
 }
 else
 {
  if (p->left != NIL && p->right == NIL)
  {
   if (p->parent == NIL)
   {
    root = p->left;
    p->left->parent = NIL;
   } 
   else if (p == p->parent->left)
   {
    p->parent->left = p->left;
    p->left->parent = p->parent;
   }
   else
   {
    p->parent->right = p->left;
    p->left->parent = p->right;
   }
   p2 = p->left;
  }
  else if (p->left == NIL && p->right != NIL)
  {
   if (p->parent == NIL)
   {
    root = p->right;
    p->right->parent = NIL;
   }
   else if (p == p->parent->left)
   {
    p->parent->left = p->right;
    p->right->parent = p->parent;
   }
   else
   {
    p->parent->right = p->right;
    p->right->parent = p->parent;
   }
   p2 = p->right;
  }
  else
  {
   if (p->parent == NIL)
   {
    root = NULL;
   }
   else if (p == p->parent->left)
   {
    p->parent->left = NIL;
   }
   else
   {
    p->parent->right = NIL;
   }
   p2 = p->right;
  }
 }
 if (p->color == RBTreeNode<T>::B)
 {
  RBDeleteFixup(p2);
 }
 return p;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::RBDeleteFixup(RBTreeNode<T> *x)
{
 if (root == NULL)
 {
  return;
 }
 while (x != root && x->color == RBTreeNode<T>::B)
 {
  if (x == x->parent->left)
  {
   RBTreeNode<T> *w = x->parent->right;
   if (w->color == RBTreeNode<T>::R)
   {
    w->color = RBTreeNode<T>::B;
    LeftRotate(x->parent);
    w = x->parent->right;
   }
   if (w->left->color == RBTreeNode<T>::B && w->right->color == RBTreeNode<T>::B)
   {
    w->color = RBTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->right->color == RBTreeNode<T>::B)
   {
    w->left->color = RBTreeNode<T>::B;
    w->color = RBTreeNode<T>::R;
    RightRotate(w);
    w = x->right->right;
    w->color = x->parent->color;
    x->parent->color = RBTreeNode<T>::B;
    w->right->color = RBTreeNode<T>::B;
    LeftRotate(x->parent);
    x = root;
   }
  }
  else
  {
   RBTreeNode<T> *w = x->parent->left;
   if (w->color == RBTreeNode<T>::R)
   {
    w->color = RBTreeNode<T>::B;
    RightRotate(x->parent);
    w = x->parent->left;
   }
   if (w->right->color == RBTreeNode<T>::B && w->left->color == RBTreeNode<T>::B)
   {
    w->color = RBTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->left->color == RBTreeNode<T>::B)
   {
    w->right->color = RBTreeNode<T>::B;
    w->color = RBTreeNode<T>::R;
    LeftRotate(w);
    w = x->parent->left;
    w->color = x->parent->color;
    x->parent->color = RBTreeNode<T>::B;
    w->left->color = RBTreeNode<T>::B;
    RightRotate(x->parent);
    x = root;
   }
  }
  x->color = RBTreeNode<T>::B;
 }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::Clear()
{
 if (root != NULL)
 {
  Destory(root);
  root = NULL;
 }
 return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void RBTree<T>::Destory(RBTreeNode<T> *p)
{
 while (p != NIL)
 {
  Destory(p->left);
  Destory(p->right);
  delete p;
  p = NIL;
 }
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
RBTree<T>::~RBTree()
{
 Clear();
 if (NIL != NULL)
 {
  delete NIL;
 }
}

原创粉丝点击