introduction to algorithms 筆記 AVLtree

//author:yydrewdrew

#define ERROR -1

template <class T>
struct AVLTreeNode
{
 T data;
 int disheight;//height(right) - height(left)
 AVLTreeNode<T> *left;
 AVLTreeNode<T> *right;
 AVLTreeNode<T> *parent;
};

template<class T>
class AVLTree
{
 public:
  AVLTree<T>(AVLTreeNode<T> *p = NULL):root(p){}
  virtual ~AVLTree<T>();
  AVLTree<T>(const AVLTree<T> &obj);
  AVLTree<T> &operator = (const AVLTree<T> &obj);
 public:
  AVLTreeNode<T> *Serach(const T& t)const;
  AVLTreeNode<T> *Insert(const T &t);
  AVLTreeNode<T> *Delete(const T &t);
  AVLTreeNode<T> *Successor(const T &t)const;
  AVLTreeNode<T> *Predecessor(const T &t)const;
  AVLTreeNode<T> *Min()const;
  AVLTreeNode<T> *Max()const;
  void Clear();
  void TreeWalk()const;
  void Swap(AVLTree &obj);
 private:
  void Clean()
  {
   root = NULL;
  }
  void Scan(AVLTreeNode<T> *p)const;
  void Destory(AVLTreeNode<T> *p);
  void InsertBalance(AVLTreeNode<T> *p);
  void DeleteBalance(AVLTreeNode<T> *p);
  void LLRotate(AVLTreeNode<T> *p);
  void LRRotate(AVLTreeNode<T> *p);
  void RLRotate(AVLTreeNode<T> *p);
  void RRRotate(AVLTreeNode<T> *p);
  void LRotate(AVLTreeNode<T> *p);
  void RRotate(AVLTreeNode<T> *p);
  void Copy(const AVLTreeNode<T> *const p);
 private:
  AVLTreeNode<T> *root;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Max()const
{
 AVLTreeNode<T> *p = NULL;
 AVLTreeNode<T> *p2 = NULL;
 while (p != NULL)
 {
  p2 = p;
  p = p->right;
 }
 return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Min()const
{
 AVLTreeNode<T> *p = root;
 AVLTreeNode<T> *p2 = NULL;
 while (p != NULL)
 {
  p2 = p;
  p = p->left;
 }
 return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T> &AVLTree<T>::operator = (const AVLTree<T> &obj)
{
 if (this != &obj)
 {
  Swap(AVLTree<T>(obj));
 }
 return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T>::AVLTree<T>(const AVLTree<T> &obj)
{
 root = NULL;
 Copy(obj.root);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Copy(const AVLTreeNode<T> *const p)
{
 if (p != NULL)
 {
  Copy(p->left);
  Insert(p->data);
  Copy(p->right);
 }
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T>::~AVLTree<T>()
{
 Destory(root);
 root = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Clear()
{
 Destory(root);
 root = NULL;
 return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Destory(AVLTreeNode<T> *p)
{
 if (p != NULL)
 {
  Destory(p->left);
  Destory(p->right);
  delete p;
  p = NULL;
 }
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Swap(AVLTree<T> &obj)
{
 std::swap(root,obj.root);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::TreeWalk()const
{
 Scan(root);
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Scan(AVLTreeNode<T> *p)const
{
 if (p == NULL)
 {
  return;
 }
 Scan(p->left);
 std::cout<<p->data<<std::endl;
 Scan(p->right);
 return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Successor(const T &t)const
{
 AVLTreeNode<T> *p = Serach(t);
 if (p->right != NULL)
 {
  AVLTree<T> tem(p->right);
  p = tem.Min();
  tem.Clean();
  return p;
 }
 else
 {
  AVLTreeNode<T> *p2 = p;
  p = p->parent;
  while (p != NULL && p2 == p->right)
  {
   p = p->parent;
  }
  return p;
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Predecessor(const T &t)const
{
 AVLTreeNode<T> * p = Serach(t);
 if (p->left != NULL)
 {
  AVLTree<T> tem(p->left);
  p = tem.Max();
  tem.Clean();
  return p;
 }
 else
 {
  AVLTreeNode<T> *p2 = p;
  p = p->parent;
  while (p != NULL && p2 == p->left)
  {
   p = p->parent;
  }
  return p;
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Serach(const T &t)const
{
 AVLTreeNode<T> *p = root;
 while (p != NULL)
 {
  if (p->data > t)
  {
   p = p->left;
  }
  else if (p->data < t)
  {
   p = p->right;
  }
  else
  {
   break;
  }
 }
 return p;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Insert(const T &t)
{
 AVLTreeNode<T> *ptem = new AVLTreeNode<T>;
 ptem->data = t;
 ptem->left = NULL;
 ptem->right = NULL;
 ptem->disheight = 0;
 AVLTreeNode<T> *p2 = NULL,*p = root;
 while (p != NULL)
 {
  p2 = p;
  if (p->data > t)
  {
   p = p->left;
  }
  else
  {
   p = p->right;
  }
 }
 if (root == NULL)
 {
  root = ptem;
  ptem->parent = NULL;
  return root;
 }
 if (p2->data > t)
 {
  p2->left = ptem;
 }
 else
 {
  p2->right = ptem;  
 }
 ptem->parent = p2;
 InsertBalance(ptem);
 return ptem;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Delete(const T &t)
{
 AVLTreeNode<T> *p = Serach(t);
 if (p == root || p == NULL)
 {
  root = NULL;
  return p;
 }
 if (p->left == NULL && p->right == NULL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = NULL;
  }
  else
  {
   p->parent->right = NULL;
  }
  DeleteBalance(p);
 }
 else if (p->left == NULL && p->right != NULL)
 {
  p->right->parent = p->parent;
  if (p == p->parent->left)
  {
   p->parent->left = p->right;
  }
  else
  {
   p->parent->right = p->right;
  }
  DeleteBalance(p);
 }
 else if (p->left != NULL && p->right == NULL)
 {
  p->left->parent = p->parent;
  if (p == p->parent->left)
  {
   p->parent->left = p->left;
  }
  else
  {
   p->parent->right = p->left;
  }
  DeleteBalance(p);
 }
 else
 {
  AVLTreeNode<T> *p2 = Successor(t);
  if (p2 != root)
  {
   if (p2 == p2->parent->left)
   {
    p2->parent->left = p2->right;
   }
   else
   {
    p2->parent->right = p2->right;
   }
  }
  AVLTreeNode<T> tem = *p;
  *p = *p2;
  p->parent = tem.parent;
  p->left = tem.left;
  p->right = tem.right;
  DeleteBalance(p2);
  *p2 = tem;
  p = p2;
 }
 return p;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::InsertBalance(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = NULL;
 AVLTreeNode<T> *p3 = NULL;
 while (p != root && p != NULL)
 {
  p3 = p2;
  p2 = p;
  p = p->parent;
  int dis = p->disheight;
  switch(dis)
  {
  case 0:
   {
    if (p2 == p->left)
    {
     p->disheight = -1;
    }
    else
    {
     p->disheight = 1;
    }
    break;
   }
  case 1:
   {
    if (p2 == p->left)
    {
     p->disheight = 0;
    }
    else
    {
     p->disheight = 2;
     if (p3 == NULL)
     {
      throw ERROR;
     }
     if (p3 == p2->right)
     {
      RRRotate(p);
     }
     else
     {
      RLRotate(p);
     }
    }
    p = root;
    break;
   }
  case -1:
   {
    if (p2 == p->left)
    {
     p->disheight = -2;
     if (p3 == NULL)
     {
      throw ERROR;
     }
     if (p3 == p->left)
     {
      LLRotate(p);
     }
     else
     {
      LRRotate(p);
     }
    }
    else
    {
     p->disheight = 0;
    }
    p = root;
    break;
   }
  default:
   {
    throw ERROR;
    break;
   }
  }
 }
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LRotate(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = p->right;
 p2->parent = p->parent;
 if (p->parent != NULL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 else
 {
  root = p2;
 }
 p->right = p2->left;
 if (p2->left != NULL)
 {
  p2->left->parent = p;
 }
 p2->left = p;
 p->parent = p2;
 return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RRotate(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = p->left;
 p2->parent = p->parent;
 if (p->parent != NULL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 else
 {
  root = p2;
 }
 p->left = p2->right;
 if (p2->right != NULL)
 {
  p2->right->parent = p;
 }
 p2->right = p;
 p->parent = p2;
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::DeleteBalance(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = NULL;
 while (p != NULL)
 {
  p2 = p->parent;
  if (p->disheight == 0)
  {
   if (p == p2->left)
   {
    p2->disheight = 1;
   }
   else
   {
    p2->disheight = -1;
   }
   p = NULL;
  }
  else if (p->disheight == 1)
  {
   if (p == p2->left)
   {
    p2->disheight = 2;
    AVLTreeNode<T> *p3 = p2->right;
    switch(p3->disheight)
    {
    case 1:
     {
      p->disheight = 0;
      p2->disheight = 0;
      LRotate(p2);
      p = p2->parent;
      break;    
     }
    case 0:
     {
      p3->disheight = -1;
      p2->disheight = 1;
      LRotate(p2);
      p = NULL;
      break;
     }
    case -1:
     {
      AVLTreeNode<T> *p4 = p3->left;
      switch(p4->disheight)
      {
      case -1:
       {
        p2->disheight = 0;
        p3->disheight = 1;
        p4->disheight = 0;
        RRotate(p3);
        LRotate(p2);
        p = p3->parent;
        break;
       }
      case 0:
       {
        p2->disheight = -1;
        p3->disheight = 0;
        p4->disheight = 0;
        RRotate(p3);
        LRotate(p2);
        p = p3->parent;
        break;
       } 
      case 1:
       {
        p2->disheight = 0;
        p3->disheight = 0;
        p4->disheight = 0;
        RRotate(p3);
        LRotate(p2);
        p = p3->parent;
        break;
       }
      default:
        throw ERROR;
      }
     }
    default:
     throw ERROR;
    }
   }
   else
   {
    p2->disheight = 0;
    p = p->parent;
   }
  }
  else if (p->disheight == -1)
  {
   if (p == p2->left)
   {
    p2->disheight = 0;
    p = p->parent;
   }
   else
   {
    p2->disheight = -2;
    AVLTreeNode<T> *p3 = p2->left;
    switch(p3->disheight)
    {
    case 1:
     {
      p->disheight = 0;
      p2->disheight = 0;
      RRotate(p2);
      p = p2->parent;
      break;  
     }
    case 0:
     {
      p3->disheight = -1;
      p2->disheight = 1;
      RRotate(p2);
      p = NULL;
      break;
     }
    case -1:
     {
      AVLTreeNode<T> *p4 = p3->left;
      switch(p4->disheight)
      {
      case -1:
       {
        p2->disheight = 0;
        p3->disheight = 1;
        p4->disheight = 0;
        LRotate(p3);
        RRotate(p2);
        p = p3->parent;
        break;
       }
      case 0:
       {
        p2->disheight = -1;
        p3->disheight = 0;
        p4->disheight = 0;
        LRotate(p3);
        RRotate(p2);
        p = p3->parent;
        break;
       } 
      case 1:
       {
        p2->disheight = 0;
        p3->disheight = 0;
        p4->disheight = 0;
        LRotate(p3);
        RRotate(p2);
        p = p3->parent;
        break;
       }
      default:
        throw ERROR;
      }
     }
    default:
     throw ERROR;
    }
   }
  }
 }
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RRRotate(AVLTreeNode<T> *p)
{
 p->disheight = 0;
 AVLTreeNode<T> *p2 = p->right;
 p2->disheight = 0;
 LRotate(p);
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RLRotate(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = p->right;
 AVLTreeNode<T> *p3 = p2->left;
 p->disheight = -1;
 p2->disheight = 0;
 p3->disheight = 0;
 RRotate(p2);
 LRotate(p);
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LLRotate(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = p->left;
 p->disheight = 0;
 p2->disheight = 0;
 RRotate(p);
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LRRotate(AVLTreeNode<T> *p)
{
 AVLTreeNode<T> *p2 = p->left;
 AVLTreeNode<T> *p3 = p->left->right;
 p->disheight = -1;
 p2->disheight = 0;
 p3->disheight = 0;
 LRotate(p2);
 RRotate(p);
 return;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章