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

introduction to algorithms 菜鸟笔记 sattree(统计树)

2008-07-24 20:30 309 查看
//author:yydrewdrew

#include <iostream>
using namespace std;

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

template <class T>
class StatTree
{
public:
StatTreeNode<T> *Select(const int st)const;
int Rank(const T &t)const;
void TreeWalk()const;
StatTreeNode<T> *Insert(const T &t);
StatTreeNode<T> *Delete(const T &t);
StatTreeNode<T> *Serach(const T &t)const;
StatTreeNode<T> *Predecesor(const T &t)const;
StatTreeNode<T> *Successor(const T &t)const;
StatTreeNode<T> *Min()const;
StatTreeNode<T> *Max()const;
void Clear();
void Swap(StatTree<T> &obj);
public:
StatTree():root(NULL),NIL(new(StatTreeNode<T>))
{
NIL->data = 0;
NIL->left = NULL;
NIL->right = NULL;
NIL->size = 0;
NIL->color = StatTreeNode<T>::B;
}
StatTree<T> &operator = (const StatTree<T> &obj);
StatTree<T>(const StatTree<T> &obj);
virtual ~StatTree();
private:
StatTree(StatTreeNode<T> *r,StatTreeNode<T> *nil):root(r),NIL(nil){}
StatTreeNode<T> * GetSelect(int st,StatTreeNode<T> *root)const;
void LeftRotate(StatTreeNode<T> *const p);
void LeftRotate(const T &t);
void RightRotate(StatTreeNode<T> *const p);
void RightRotate(const T &t);
void StatTreeInsertFixup(StatTreeNode<T> *p);
void StatTreeDeleteFixup(StatTreeNode<T> *p);
void Clean()
{
root = NULL;
NIL = NULL;
}
void Destory(StatTreeNode<T> *p);
void Scan(StatTreeNode<T> *root)const;
void Copy(StatTreeNode<T> *p,const StatTree<T> &obj);
void MaintenanceSize(StatTreeNode<T> *p);
private:
StatTreeNode<T> *root;
StatTreeNode<T> *NIL;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
int StatTree<T>::Rank(const T &t)const
{
StatTreeNode<T> *p = Serach(t);
int st = p->left->size + 1;
while (p != root)
{
if (p == p->parent->right)
{
st = st + p->parent->left->size + 1;
}
p = p->parent;
}
return st;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Select(const int st)const
{
return(GetSelect(st,root));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::GetSelect(int st,StatTreeNode<T> *root)const
{
if (st <= 0)
{
return NULL;
}
int size = root->left->size + 1;
if (st == size)
{
return root;
}
else if(st < size)
{
GetSelect(st,root->left);
}
else
{
GetSelect(st - size,root->right);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Swap(StatTree<T> &obj)
{
std::swap(root,obj.root);
std::swap(NIL,obj.NIL);
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T> &StatTree<T>::operator = (const StatTree<T> &obj)
{
if (this != &obj)
{
Swap(StatTree<T>(obj));
}
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Copy(StatTreeNode<T> *p,const StatTree<T> &obj)
{
if (p != obj.NIL)
{
Copy(p->left,obj);
Insert(p->data);
Copy(p->right,obj);
}
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T>::StatTree(const StatTree<T> &obj)
{
root = NULL;
NIL = new StatTreeNode<T>;
NIL->data = 0;
NIL->left = NULL;
NIL->right = NULL;
NIL->color = StatTreeNode<T>::B;
Copy(obj.root,obj);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Scan(StatTreeNode<T> *root)const
{
if (root == NULL || root == NIL)
{
return;
}
Scan(root->left);
cout<<root->data<<endl;
Scan(root->right);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::TreeWalk()const
{
Scan(root);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Min()const
{
if (root == NULL)
{
return NULL;
}
StatTreeNode<T> *p = root;
StatTreeNode<T> *p2 = NULL;
while (p != NIL)
{
p2 = p;
p = p->left;
}
return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Max()const
{
if (root == NULL)
{
return NULL;
}
StatTreeNode<T> *p = root;
StatTreeNode<T> *p2 = NULL;
while (p != NIL)
{
p2 = p;
p = p->right;
}
return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Serach(const T &t)const
{
if (root == NULL)
{
return NULL;
}
StatTreeNode<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>
StatTreeNode<T> *StatTree<T>::Successor(const T &t)const
{
StatTreeNode<T> *p = Serach(t);
if (p->right != NIL)
{
StatTree<T> treetem(p->right,NIL);
p = treetem.Min();
treetem.Clean();
return p;
}
StatTreeNode<T> *p2 = p->parent;
while (p2 != NIL && p == p2->right)
{
p = p2;
p2 = p2->parent;
}
return p2;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Predecesor(const T &t)const
{
StatTreeNode<T> *p = Serach(t);
if (p->left != NIL)
{
StatTree<T> treetem(p->left,NIL);
p = treetem.Max();
treetem.Clean();
return p;
}
StatTreeNode<T> *p2 = p->parent;
while (p2 != NIL && p == p2->left)
{
p = p2;
p2 = p2->parent;
}
return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::LeftRotate(StatTreeNode<T> *const p)
{
if (p == NULL || p == NIL)
{
return;
}
if(p->right == NIL)
{
return;
}
StatTreeNode<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;
p2->size = p->size;
p->size = p->left->size + p->right->size + 1;
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::LeftRotate(const T &t)
{
StatTreeNode<T> *p = Serach(t);
LeftRotate(p);
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::RightRotate(StatTreeNode<T> *const p)
{
if (p == NULL || p == NIL)
{
return;
}
if (p->left == NIL)
{
return;
}
StatTreeNode<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;
p2->size = p->size;
p->size = p->left->size + p->right->size + 1;
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::RightRotate(const T &t)
{
StatTreeNode<T> *p = Serach(t);
RightRotate(p);
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Insert(const T &t)
{
StatTreeNode<T> *p = root;
StatTreeNode<T> *p2 = NULL;
while (p != NIL && p != NULL)
{
p2 = p;
if (t > p->data)
{
p = p->right;
}
else
{
p = p->left;
}
}
StatTreeNode<T> *ptem = new StatTreeNode<T>;
ptem->data = t;
ptem->size = 1;
ptem->left = NIL;
ptem->right = NIL;
if (p == NULL)
{
root = ptem;
root->color = StatTreeNode<T>::B;
root->parent = NIL;
}
else
{
if (t > p2->data)
{
p2->right = ptem;
ptem->color = StatTreeNode<T>::R;
ptem->parent = p2;
}
else
{
p2->left = ptem;
ptem->color = StatTreeNode<T>::R;
ptem->parent = p2;
}
}
MaintenanceSize(ptem);
StatTreeInsertFixup(ptem);
return ptem;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::MaintenanceSize(StatTreeNode<T> *p)
{
p = p->parent;
while (p != NIL)
{
++p->size;
p = p->parent;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::StatTreeInsertFixup(StatTreeNode<T> *p)
{
while (p->parent->color == StatTreeNode<T>::R)
{
if (p->parent == p->parent->parent->left)
{
StatTreeNode<T> *y = p->parent->parent->right;
if (y->color == StatTreeNode<T>::R)
{
p->color = StatTreeNode<T>::B;
y->color = StatTreeNode<T>::B;
p->parent->parent->color = StatTreeNode<T>::R;
p = p->parent;
}
else if (p == p->parent->right)
{
p = p->parent;
LeftRotate(p);
}
p->parent->color = StatTreeNode<T>::B;
p->parent->parent->color = StatTreeNode<T>::R;
RightRotate(p);
}
else
{
StatTreeNode<T> *y = p->parent->parent->left;
if (y->color == StatTreeNode<T>::R)
{
p->color = StatTreeNode<T>::B;
y->color = StatTreeNode<T>::B;
p->parent->parent->color = StatTreeNode<T>::R;
p = p->parent;
}
else if (p == p->parent->left)
{
p = p->parent;
RightRotate(p);
}
p->parent->color = StatTreeNode<T>::B;
p->parent->parent->color = StatTreeNode<T>::R;
LeftRotate(p);
}
}
root->color = StatTreeNode<T>::B;
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Delete(const T &t)
{
StatTreeNode<T> *p = Serach(t);
StatTreeNode<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 == StatTreeNode<T>::B)
{
StatTreeDeleteFixup(p2);
}
return p;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::StatTreeDeleteFixup(StatTreeNode<T> *x)
{
if (root == NULL)
{
return;
}
while (x != root && x->color == StatTreeNode<T>::B)
{
if (x == x->parent->left)
{
StatTreeNode<T> *w = x->parent->right;
if (w->color == StatTreeNode<T>::R)
{
w->color = StatTreeNode<T>::B;
LeftRotate(x->parent);
w = x->parent->right;
}
if (w->left->color == StatTreeNode<T>::B && w->right->color == StatTreeNode<T>::B)
{
w->color = StatTreeNode<T>::R;
x = x->parent;
}
else if (w->right->color == StatTreeNode<T>::B)
{
w->left->color = StatTreeNode<T>::B;
w->color = StatTreeNode<T>::R;
RightRotate(w);
w = x->right->right;
w->color = x->parent->color;
x->parent->color = StatTreeNode<T>::B;
w->right->color = StatTreeNode<T>::B;
LeftRotate(x->parent);
x = root;
}
}
else
{
StatTreeNode<T> *w = x->parent->left;
if (w->color == StatTreeNode<T>::R)
{
w->color = StatTreeNode<T>::B;
RightRotate(x->parent);
w = x->parent->left;
}
if (w->right->color == StatTreeNode<T>::B && w->left->color == StatTreeNode<T>::B)
{
w->color = StatTreeNode<T>::R;
x = x->parent;
}
else if (w->left->color == StatTreeNode<T>::B)
{
w->right->color = StatTreeNode<T>::B;
w->color = StatTreeNode<T>::R;
LeftRotate(w);
w = x->parent->left;
w->color = x->parent->color;
x->parent->color = StatTreeNode<T>::B;
w->left->color = StatTreeNode<T>::B;
RightRotate(x->parent);
x = root;
}
}
x->color = StatTreeNode<T>::B;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Clear()
{
if (root != NULL)
{
Destory(root);
root = NULL;
}
return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Destory(StatTreeNode<T> *p)
{
while (p != NIL)
{
Destory(p->left);
Destory(p->right);
delete p;
p = NIL;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T>::~StatTree()
{
Clear();
if (NIL != NULL)
{
delete NIL;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: