introduction to algorithms 笔记 interval tree(区间树)

//author:yydrewdrew 

#include <iostream>

using namespace std;
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define ERROR -1

template <class T>
struct IntervalTreeNode
{
 T leftvalue;
 T rightvalue;
 T maxrightvalue;
 IntervalTreeNode *parent;
 IntervalTreeNode *left;
 IntervalTreeNode *right;
 enum Color{R,B};
 Color color;
};


template <class T>
class IntervalTree
{
public:
 void TreeWalk()const;
 IntervalTreeNode<T> *Insert(const T &left,const T &right);
 IntervalTreeNode<T> *Delete(const T &left,const T &right);
 IntervalTreeNode<T> *Serach(const T &left,const T &right)const;
 IntervalTreeNode<T> *Predecesor(const T &left,const T &right)const;
 IntervalTreeNode<T> *Successor(const T &left,const T &right)const;
 IntervalTreeNode<T> *Min()const;
 IntervalTreeNode<T> *Max()const;
 void Clear();
 void Swap(IntervalTree<T> &obj);
public:
 IntervalTree():root(NULL),NIL(new(IntervalTreeNode<T>))
 {
  NIL->leftvalue = 0;
  NIL->left = NULL;
  NIL->right = NULL;
  NIL->maxrightvalue = 0;
  NIL->color = IntervalTreeNode<T>::B;
 }
 IntervalTree<T> &operator = (const IntervalTree<T> &obj);
 IntervalTree<T>(const IntervalTree<T> &obj);
 virtual ~IntervalTree();
private:
 IntervalTree(IntervalTreeNode<T> *r,IntervalTreeNode<T> *nil):root(r),NIL(nil){}
 void LeftRotate(IntervalTreeNode<T> *const p);;
 void RightRotate(IntervalTreeNode<T> *const p);
 void IntervalTreeInsertFixup(IntervalTreeNode<T> *p);
 void IntervalTreeDeleteFixup(IntervalTreeNode<T> *p);
 void Clean()
 {
  root = NULL;
  NIL = NULL;
 }
 void Destory(IntervalTreeNode<T> *p);
 void Scan(IntervalTreeNode<T> *root)const;
 void Copy(IntervalTreeNode<T> *p,const IntervalTree<T> &obj);
 void MaintenanceSize(IntervalTreeNode<T> *p);
 bool IsOverlap(const IntervalTreeNode<T> *p1,IntervalTreeNode<T> *p2)const;
 IntervalTreeNode<T> *Find(const T &left,const T &right)const;
 void MaintenanceMaxrightValue(IntervalTreeNode<T> *p);
private:
 IntervalTreeNode<T> *root;
 IntervalTreeNode<T> *NIL;
};
/
template<class T>
bool IntervalTree<T>::IsOverlap(const IntervalTreeNode<T> *p1,IntervalTreeNode<T> *p2)const
{
 if (p1 == NIL || p2 == NIL)
 {
  return false;
 }
 return(p1->rightvalue >= p2->leftvalue && p1->leftvalue <= p2->rightvalue);
}

template<class T>
void IntervalTree<T>::Swap(IntervalTree<T> &obj)
{
 std::swap(root,obj.root);
 std::swap(NIL,obj.NIL);
 return;
}

template<class T>
IntervalTree<T> &IntervalTree<T>::operator = (const IntervalTree<T> &obj)
{
 if (this != &obj)
 {
  Swap(IntervalTree<T>(obj));
 }
 return *this;
}

template<class T>
void IntervalTree<T>::Copy(IntervalTreeNode<T> *p,const IntervalTree<T> &obj)
{
 if (p != obj.NIL)
 {
  Copy(p->left,obj);
  Insert(p->leftvalue,p->rightvalue);
  Copy(p->right,obj);
 }
 return;
}
///
template<class T>
IntervalTree<T>::IntervalTree(const IntervalTree<T> &obj)
{
 root = NULL;
 NIL = new IntervalTreeNode<T>;
 NIL->leftvalue = 0;
 NIL->rightvalue = 0;
 NIL->maxrightvalue = 0;
 NIL->left = NULL;
 NIL->right = NULL;
 NIL->color = IntervalTreeNode<T>::B;
 Copy(obj.root,obj);
}
///
template<class T>
void IntervalTree<T>::Scan(IntervalTreeNode<T> *root)const
{
 if (root == NULL || root == NIL)
 {
  return;
 }
 Scan(root->left);
 std::cout << root->leftvalue << "   " << root->rightvalue << std::endl;
 Scan(root->right);
}
/
template<class T>
void IntervalTree<T>::TreeWalk()const
{
 Scan(root);
}
///
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Min()const
{
 if (root == NULL)
 {
  return NULL;
 }
 IntervalTreeNode<T> *p = root;
 IntervalTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->left;
 }
 return p2;
}
//
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Max()const
{
 if (root == NULL)
 {
  return NULL;
 }
 IntervalTreeNode<T> *p = root;
 IntervalTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->right;
 }
 return p2;
}
///
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Find(const T &left,const T &right)const
{
 if (root == NULL)
 {
  return NULL;
 }
 IntervalTreeNode<T> *p = root;
 while (p != NIL && !(left == p->leftvalue && right == p->rightvalue))
 {
  if (p->left->maxrightvalue > left)
  {
   p = p->left;
  }
  else
  {
   p = p->right;
  }
 }
 return p;
}
//
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Serach(const T &left,const T &right)const
{
 if (root == NULL)
 {
  return NULL;
 }
 IntervalTreeNode<T> *p = root;
 IntervalTreeNode<T> tem = {left,right};
 while (p != NIL && !IsOverlap(p,&tem))
 {
  if (p->left->maxrightvalue > left)
  {
   p = p->left;
  }
  else
  {
   p = p->right;
  }
 }
 return p;
}
/
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Successor(const T &left,const T &right)const
{
 IntervalTreeNode<T> *p = Serach(left,right);
 if (p->right != NIL)
 {
  IntervalTree<T> treetem(p->right,NIL);
  p = treetem.Min();
  treetem.Clean();
  return p;
 }
 IntervalTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->right)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}

template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Predecesor(const T &left,const T &right)const
{
 IntervalTreeNode<T> *p = Serach(t);
 if (p->left != NIL)
 {
  IntervalTree<T> treetem(p->left,NIL);
  p = treetem.Max();
  treetem.Clean();
  return p;
 }
 IntervalTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->left)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}
//
template<class T>
void IntervalTree<T>::LeftRotate(IntervalTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if(p->right == NIL)
 {
  return;
 }
 IntervalTreeNode<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;
 p->maxrightvalue = max(max(p->left->maxrightvalue,p->right->maxrightvalue),p->rightvalue);
 p2->maxrightvalue = max(max(p2->left->maxrightvalue,p2->right->maxrightvalue),p2->rightvalue);
 return;
}
///
template<class T>
void IntervalTree<T>::RightRotate(IntervalTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if (p->left == NIL)
 {
  return;
 }
 IntervalTreeNode<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;
 p->maxrightvalue = max(max(p->left->maxrightvalue,p->right->maxrightvalue),p->rightvalue);
 p2->maxrightvalue = max(max(p2->left->maxrightvalue,p2->right->maxrightvalue),p2->maxrightvalue);
 return;
}
///
template<class T>
void IntervalTree<T>::MaintenanceMaxrightValue(IntervalTreeNode<T> *p)
{
 while (p != NIL)
 {
  p->maxrightvalue = max(max(p->left->maxrightvalue,p->right->maxrightvalue),p->maxrightvalue);
  p = p->parent;
 }
 return;
}
///
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Insert(const T &left,const T &right)
{
 if (left > right)
 {
  throw ERROR;
 }
 IntervalTreeNode<T> *p = root;
 IntervalTreeNode<T> *p2 = NULL;
 while (p != NIL && p != NULL)
 {
  p2 = p;
  if (left > p->leftvalue)
  {
   p = p->right;
  }
  else
  {
   p = p->left;
  }
 }
 IntervalTreeNode<T> *ptem = new IntervalTreeNode<T>;
 ptem->leftvalue = left;
 ptem->rightvalue = right;
 ptem->maxrightvalue = ptem->rightvalue;
 ptem->left = NIL;
 ptem->right = NIL;
 if (p == NULL)
 {
  root = ptem;
  root->color = IntervalTreeNode<T>::B;
  root->parent = NIL;
 }
 else
 {
  if (left > p2->leftvalue)
  {
   p2->right = ptem;
   ptem->color = IntervalTreeNode<T>::R;
   ptem->parent = p2;
  }
  else
  {
   p2->left = ptem;
   ptem->color = IntervalTreeNode<T>::R;
   ptem->parent = p2;
  }
 }
 MaintenanceMaxrightValue(ptem);
 IntervalTreeInsertFixup(ptem);
 return ptem;
}

template<class T>
void IntervalTree<T>::IntervalTreeInsertFixup(IntervalTreeNode<T> *p)
{
 while (p->parent->color == IntervalTreeNode<T>::R)
 {
  if (p->parent == p->parent->parent->left)
  {
   IntervalTreeNode<T> *y = p->parent->parent->right;
   if (y->color == IntervalTreeNode<T>::R)
   {
    p->color = IntervalTreeNode<T>::B;
    y->color = IntervalTreeNode<T>::B;
    p->parent->parent->color = IntervalTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->right)
   {
    p = p->parent;
    LeftRotate(p);
   }
   p->parent->color = IntervalTreeNode<T>::B;
   p->parent->parent->color = IntervalTreeNode<T>::R;
   RightRotate(p);
  }
  else
  {
   IntervalTreeNode<T> *y = p->parent->parent->left;
   if (y->color == IntervalTreeNode<T>::R)
   {
    p->color = IntervalTreeNode<T>::B;
    y->color = IntervalTreeNode<T>::B;
    p->parent->parent->color = IntervalTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->left)
   {
    p = p->parent;
    RightRotate(p);
   }
   p->parent->color = IntervalTreeNode<T>::B;
   p->parent->parent->color = IntervalTreeNode<T>::R;
   LeftRotate(p);
  }
 }
 root->color = IntervalTreeNode<T>::B;
 return;
}
///
template<class T>
IntervalTreeNode<T> *IntervalTree<T>::Delete(const T &left,const T &right)
{
 IntervalTreeNode<T> *p = Find(left,right);
 if (p == NULL)
 {
  return NIL;
 }
 IntervalTreeNode<T> *p2 = p;
 if (p->left != NIL && p->right !=NIL)
 {
  p2 = Successor(left,right);
  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;
  std::swap(p->leftvalue,p2->leftvalue);
  std::swap(p->rightvalue,p2->rightvalue);
  p->maxrightvalue = max(max(p->left->maxrightvalue,p->right->maxrightvalue),p->rightvalue);
  p2->maxrightvalue = max(max(p2->left->maxrightvalue,p2->right->maxrightvalue),p->maxrightvalue);
  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;
  }
 }
 MaintenanceMaxrightValue(p2);
 if (p->color == IntervalTreeNode<T>::B)
 {
  IntervalTreeDeleteFixup(p2);
 }
 return p;
}
//
template<class T>
void IntervalTree<T>::IntervalTreeDeleteFixup(IntervalTreeNode<T> *x)
{
 if (root == NULL)
 {
  return;
 }
 while (x != root && x->color == IntervalTreeNode<T>::B)
 {
  if (x == x->parent->left)
  {
   IntervalTreeNode<T> *w = x->parent->right;
   if (w->color == IntervalTreeNode<T>::R)
   {
    w->color = IntervalTreeNode<T>::B;
    LeftRotate(x->parent);
    w = x->parent->right;
   }
   if (w->left->color == IntervalTreeNode<T>::B && w->right->color == IntervalTreeNode<T>::B)
   {
    w->color = IntervalTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->right->color == IntervalTreeNode<T>::B)
   {
    w->left->color = IntervalTreeNode<T>::B;
    w->color = IntervalTreeNode<T>::R;
    RightRotate(w);
    w = x->right->right;
    w->color = x->parent->color;
    x->parent->color = IntervalTreeNode<T>::B;
    w->right->color = IntervalTreeNode<T>::B;
    LeftRotate(x->parent);
    x = root;
   }
  }
  else
  {
   IntervalTreeNode<T> *w = x->parent->left;
   if (w->color == IntervalTreeNode<T>::R)
   {
    w->color = IntervalTreeNode<T>::B;
    RightRotate(x->parent);
    w = x->parent->left;
   }
   if (w->right->color == IntervalTreeNode<T>::B && w->left->color == IntervalTreeNode<T>::B)
   {
    w->color = IntervalTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->left->color == IntervalTreeNode<T>::B)
   {
    w->right->color = IntervalTreeNode<T>::B;
    w->color = IntervalTreeNode<T>::R;
    LeftRotate(w);
    w = x->parent->left;
    w->color = x->parent->color;
    x->parent->color = IntervalTreeNode<T>::B;
    w->left->color = IntervalTreeNode<T>::B;
    RightRotate(x->parent);
    x = root;
   }
  }
  x->color = IntervalTreeNode<T>::B;
 }
}

template<class T>
void IntervalTree<T>::Clear()
{
 if (root != NULL)
 {
  Destory(root);
  root = NULL;
 }
 return;
}
//
template<class T>
void IntervalTree<T>::Destory(IntervalTreeNode<T> *p)
{
 while (p != NIL)
 {
  Destory(p->left);
  Destory(p->right);
  delete p;
  p = NIL;
 }
 return;
}

template<class T>
IntervalTree<T>::~IntervalTree()
{
 Clear();
 if (NIL != NULL)
 {
  delete NIL;
 }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值