您的位置:首页 > 编程语言 > Go语言

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

2008-07-24 20:35 381 查看
//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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: