T_tree 文件:
#ifndef T_TREE_H
#define T_TREE_H
#include "t_node.h"
//下面是 T 树的定义;
class t_tree
{
public:
//构造函数;
t_tree():root(NULL){}
//添加数据;
bool add(int data);
//删除数据;
bool remove(int data);
//以中序的方式 遍历 T 树 中 的数据;
void display();
//析构函数;
~t_tree();
private:
//根节点的指针;
t_node * root;
//四种方式 的旋转,
//分别是 LL 旋转,RR 旋转,LR 旋转,RL 旋转;
// pointer 是需要旋转的子树的根节点,
//返回的是 旋转后的子树的根节点;
t_node * LLsingleRotation(t_node * pointer);
t_node * RRsingleRotation(t_node * pointer);
t_node * RLdoubleRotation(t_node * pointer);
t_node * LRdoubleRotation(t_node * pointer);
//查询 pointer 节点 中的数据中是否 存在 data,
//如果 返回 true ,说明存在,index 记录data 所在的下标;
//如果 返回 false ,说明不存在,index 记录 data 插入时应该处于的位置下标;
bool find_data(t_node * pointer,int data,int & index);
//执行 添加 操作时 需要的 函数,由 add() 调用;
//data 是 需要 插入 的数据;
//当返回值 是0 时,表示插入操作没有导致 以 pointer 为根节点的子树的高度发生变化;
//当返回值是 1 时, 表示插入操作导致了 子树的高度增加;
int insert(t_node *& pointer,int data);
//执行 删除 操作时 需要的 函数, 由remove(t_node *& pointer,int data) 调用;
//其作用是返回pointer 子树 的最大值 来代替 原来要删除的数据;
//flag 表示 该操作是否导致 子树 的高度发生变化;
//返回值表示 要寻找的最大值;
int remove_helper(t_node *& pointer, int & flag);
//执行 删除 操作时 需要的 函数, 由remove() 调用;
//返回值表示 该删除操作是否导致 pointer 子树 高度发生变化;
int remove(t_node *& pointer,int data);
//由 display() 函数 调用;
void display(t_node * pointer);
//由 析构 函数 调用;
//释放 T 树 的空间;
void deletree(t_node * pointer);
};
t_node * t_tree::LLsingleRotation(t_node * pointer)
{
t_node * b=pointer->pleft;
//如果 b 节点是半叶节点,且 节点中数据 数目 少于临界值;
//需要 b 向 b 的左节点借数据,否则 b 节点 旋转后将成为内部节点,
//这将破坏 T 树的规则;
if(b->is_half_leaf() && b->data_num<MAX_NUM/2)
{
//需要借的数据的数目;
int step;
if(MAX_NUM-b->data_num > b->pleft->data_num)
step=b->pleft->data_num;
else
step=MAX_NUM-b->data_num;
for(int i=b->data_num-1;i>=0;i--)
b->data[i+step]=b->data[i];
for(int i=0;i<step;i++)
b->data[i]=b->pleft->data[b->pleft->data_num-step+i];
b->data_num+=step;
b->pleft->data_num-=step;
//如果b 的 左节点 已经为空,应该将其删除,
//且 不必 再旋转了;
if(0==b->pleft->data_num)
{
delete b->pleft;
b->pleft=NULL;
//调整平衡因子;
pointer->bf=-1;
b->bf=0;
return pointer;
}
}
//进行旋转操作;
pointer->pleft=b->pright;
b->pright=pointer;
//调整平衡因子;
if(0==b->bf)
{
b->bf=1;
pointer->bf=-1;
}
else
{
b->bf=0;
pointer->bf=0;
}
return b;
}
t_node * t_tree::RRsingleRotation(t_node * pointer)
{
t_node * b=pointer->pright;
//同上;
if(b->is_half_leaf() && b->data_num<MAX_NUM/2)
{
int step;
if(MAX_NUM- b->data_num > b->pright->data_num)
step=b->pright->data_num;
else
step=MAX_NUM- b->data_num;
for(int i=0;i<step;i++)
b->data[b->data_num+i]=b->pright->data[i];
b->data_num+=step;
b->pright->data_num-=step;
for(int i=0;i<b->pright->data_num;i++)
b->pright->data[i]=b->pright->data[i+step];
//如果 b 的有节点 已经为空,应该将其删除;
//且不必再旋转;
if(0==b->pright->data_num)
{
delete b->pright;
b->pright=NULL;
pointer->bf=1;
b->bf=0;
return pointer;
}
}
//进行旋转操作;
pointer->pright=b->pleft;
b->pleft=pointer;
//调整平衡因子;
if(0==b->bf)
{
b->bf=-1;
pointer->bf=1;
}
else
{
pointer->bf=0;
b->bf=0;
}
return b;
}
t_node * t_tree::LRdoubleRotation(t_node * pointer)
{
t_node * b=pointer->pleft;
t_node * c=b->pright;
//c 节点是半叶节点,且 数据 的数目少于临界值;
if(c->is_half_leaf() && c->data_num<MAX_NUM/2)
{
//左子树不为空;
if(NULL!=c->pleft)
{
int step;
if(MAX_NUM - c->data_num> c->pleft->data_num)
step=c->pleft->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=c->data_num-1;i>=0;i--)
c->data[i+step]=c->data[i];
for(int i=0;i<step;i++)
c->data[i]=c->pleft->data[c->pleft->data_num - step + i];
c->data_num+=step;
c->pleft->data_num-=step;
//如果c 的 左子树 为空,应该删除,
//且不必再旋转;
if(0==c->pleft->data_num)
{
delete c->pleft;
c->pleft=NULL;
//调整平衡因子;
c->bf=0;
b->bf=0;
pointer->bf=-1;
return pointer;
}
}
else//右子树不为空
{
int step;
if(MAX_NUM-c->data_num > c->pright->data_num)
step=c->pright->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=0;i<step;i++)
c->data[c->data_num + i]=c->pright->data[i];
c->data_num+=step;
c->pright->data_num-=step;
for(int i=0;i<c->pright->data_num;i++)
c->pright->data[i]=c->pright->data[i+step];
//如果 c 的右子树为空,将其删除,
//且不必旋转;
if(0==c->pright->data_num)
{
delete c->pright;
c->pright=NULL;
//调整平衡因子;
c->bf=0;
b->bf=0;
pointer->bf=-1;
return pointer;
}
}
}
//c 节点 为叶节点,且数据的数目少于临界值;
//向 b 节点 借数据 ,
else if(c->is_leaf() && c->data_num<MAX_NUM/2)
{
int step;
if(MAX_NUM - c->data_num > b->data_num)
step=b->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=c->data_num -1;i>=0;i--)
c->data[i+step]=c->data[i];
for(int i=0;i<step;i++)
c->data[i]=b->data[b->data_num - step + i];
c->data_num+=step;
b->data_num-=step;
//如果 b 节点为空,删除 b 节点,
//用 c 节点 代替 b 节点;
if(0==b->data_num)
{
pointer->pleft=c;
delete b;
//调整平衡因子;
c->bf=0;
pointer->bf=-1;
return pointer;
}
}
//进行旋转操作;
b->pright=c->pleft;
pointer->pleft=c->pright;
c->pleft=b;
c->pright=pointer;
//调整平衡因子;
if(0==c->bf)
{
pointer->bf=0;
b->bf=0;
}
else if(1==c->bf)
{
b->bf=-1;
c->bf=0;
pointer->bf=0;
}
else
{
pointer->bf=1;
b->bf=0;
c->bf=0;
}
return c;
}
t_node * t_tree::RLdoubleRotation(t_node * pointer)
{
t_node * b=pointer->pright;
t_node * c=b->pleft;
//如果 c 节点是半叶节点,且数据数目小于临界值;
if(c->is_half_leaf() && c->data_num<MAX_NUM/2)
{
//左子树不为空;
if(NULL!=c->pleft)
{
int step;
if(MAX_NUM - c->data_num > c->pleft->data_num)
step=c->pleft->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=c->data_num-1;i>=0;i--)
c->data[i+step]=c->data[i];
for(int i=0;i<step;i++)
c->data[i]=c->pleft->data[c->pleft->data_num - step + i];
c->data_num+=step;
c->pleft->data_num-=step;
//如果 左子树 为空,
//将其删除,且不再旋转;
if(0==c->pleft->data_num)
{
delete c->pleft;
c->pleft=NULL;
//调整平衡因子;
c->bf=0;
b->bf=0;
pointer->bf=1;
return pointer;
}
}
else//右子树不为空;
{
int step;
if(MAX_NUM - c->data_num > c->pright->data_num)
step=c->pright->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=0;i<step;i++)
c->data[c->data_num + i]=c->pright->data[i];
c->data_num+=step;
c->pright->data_num-=step;
for(int i=0;i<c->pright->data_num;i++)
c->pright->data[i]=c->pright->data[step+i];
//如果 右子节点 为空,
//将其删除,且不必旋转;
if(0==c->pright->data_num)
{
delete c->pright;
c->pright=NULL;
//调整平衡因子;
c->bf=0;
b->bf=0;
pointer->bf=1;
return pointer;
}
}
}
//c 节点为叶节点,且数据数目小于临界值;
//从 b 节点 借数据;
else if(c->is_leaf() && c->data_num<MAX_NUM/2)
{
int step;
if(MAX_NUM - c->data_num > b->data_num)
step=b->data_num;
else
step=MAX_NUM - c->data_num;
for(int i=0;i<step;i++)
c->data[c->data_num + i]=b->data[i];
c->data_num+=step;
b->data_num-=step;
for(int i=0;i<b->data_num;i++)
b->data[i]=b->data[step+i];
//如果 b 节点为空;
//删除 b 节点,用 c 节点替换之;
if(0==b->data_num)
{
pointer->pright=c;
delete b;
//调整平衡因子;
c->bf=0;
pointer->bf=1;
return pointer;
}
}
//进行旋转操作;
pointer->pright=c->pleft;
b->pleft=c->pright;
c->pleft=pointer;
c->pright=b;
//调整平衡因子;
if(0==c->bf)
{
pointer->bf=0;
b->bf=0;
}
else if(1==c->bf)
{
pointer->bf=-1;
b->bf=0;
c->bf=0;
}
else
{
pointer->bf=0;
b->bf=1;
c->bf=0;
}
return c;
}
bool t_tree::find_data(t_node * pointer,int data,int & index)
{
//运用二分查找及插入算法;
int * array=pointer->data;
int middle,low=0,high=pointer->data_num-1;
while(low<=high)
{
middle=(high+low)/2;
if(array[middle]==data)
{
index=middle;
return true;
}
else if(array[middle]>data)
high=middle-1;
else
low=middle+1;
}
index=low;
return false;
}
int t_tree::insert(t_node *& pointer,int data)
{
//pointer 节点 为空节点;
if(NULL==pointer)
{
pointer=new t_node;
pointer->data[0]=data;
pointer->data_num++;
//因为 以 pointer 为根节点的子树高度发生变化;
//所以返回一;
return 1;
}
//data 的范围落入左子树;
if(pointer->get_min()>data)
{
if(NULL==pointer->pleft)
{
if(MAX_NUM==pointer->data_num)
{
pointer->pleft=new t_node;
pointer->pleft->data[0]=data;
pointer->pleft->data_num++;
//左子树高度增加,调整平衡因子;
return --pointer->bf;
}
//将data 作为最小值放在这个节点里面;
for(int i=pointer->data_num-1;i>=0;i--)
pointer->data[i+1]=pointer->data[i];
pointer->data[0]=data;
pointer->data_num++;
return 0;
}
//在左子树中的插入操作为引起左子树高度变化;
if(0==insert(pointer->pleft,data))
return 0;
//否则,如果 pointer bf==-1
//需要进行旋转操作;
else if(-1==pointer->bf)
{
if(pointer->pleft->bf<0)
pointer=LLsingleRotation(pointer);
else
pointer=LRdoubleRotation(pointer);
//插入操作引起的不平衡,
//旋转一次就可以解决问题了;
return 0;
}
//左子树高度增加,调整平衡因子;
return --pointer->bf;
}
//data 的范围落入右子树;
else if(pointer->get_max()<data)
{
if(NULL==pointer->pright)
{
if(MAX_NUM==pointer->data_num)
{
pointer->pright=new t_node;
pointer->pright->data[0]=data;
pointer->pright->data_num++;
return ++pointer->bf;
}
//将data 作为最大值放在这个节点里面;
pointer->data[pointer->data_num]=data;
pointer->data_num++;
return 0;
}
//在右子树进行的插入操作未引起子树的高度变化;
if(0==insert(pointer->pright,data))
return 0;
//否则 可能 会引起旋转操作;
if(1==pointer->bf)
{
if(pointer->pright->bf<0)
pointer=RLdoubleRotation(pointer);
else
pointer=RRsingleRotation(pointer);
return 0;
}
//右子树高度发生变化,调整平衡因子;
return ++pointer->bf;
}
//data 的范围落入该节点内;
else
{
int index=0;
int min;
//重复插入,直接返回;
if(find_data(pointer,data,index))
return 0;
if(MAX_NUM==pointer->data_num)
{
min=pointer->data[0];
for(int i=0;i<pointer->data_num-1;i++)
pointer->data[i]=pointer->data[i+1];
index--;
for(int i=pointer->data_num-2;i>=index;i--)
pointer->data[i+1]=pointer->data[i];
pointer->data[index]=data;
//将 min 作为新的data 继续 进行 插入操作;
if(0==insert(pointer->pleft,min))
return 0;
if(-1==pointer->bf)
{
if(pointer->pleft->bf<0)
pointer=LLsingleRotation(pointer);
else
pointer=LRdoubleRotation(pointer);
return 0;
}
return -- pointer->bf;
}
else
{
for(int i=pointer->data_num-1;i>=index;i--)
pointer->data[i+1]=pointer->data[i];
pointer->data[index]=data;
pointer->data_num++;
return 0;
}
}
}
int t_tree::remove(t_node *& pointer, int data)
{
//无法进行删除操作,返回;
if(NULL==pointer)
return 0;
if(pointer->get_min()>data)
{
//标记子树高度是否变化;
int flag=0;
//在左子树的删除操作未导致子树高度变化;
if(0==remove(pointer->pleft,data))
return 0;
//较矮的子树 被削短,pointer 子树高度不会变化;
if(pointer->bf>=0)
flag=0;
//否则;
else
flag=1;
//调整平衡因子;
pointer->bf++;
//删除导致pointer 子树不平衡,需要调整;
if(pointer->bf>1)
{
if(0==pointer->pright->bf)
{
//旋转未导致子树高度变化;
flag=0;
pointer=RRsingleRotation(pointer);
}
else if(1==pointer->pright->bf)
{
//旋转导致子树高度发生变化;
flag=1;
pointer=RRsingleRotation(pointer);
}
else
{
flag=1;
pointer=RLdoubleRotation(pointer);
}
}
return flag;
}
if(pointer->get_max()<data)
{
//原理同上;
if(0==remove(pointer->pright,data))
return 0;
int flag=0;
if(pointer->bf<=0)
flag=0;
else
flag=1;
pointer->bf--;
if(pointer->bf<-1)
{
if(0==pointer->pleft->bf)
{
flag=0;
pointer=LLsingleRotation(pointer);
}
else if(-1==pointer->pleft->bf)
{
flag=1;
pointer=LLsingleRotation(pointer);
}
else
{
flag=1;
pointer=LRdoubleRotation(pointer);
}
}
return flag;
}
int index=0;
//没有找到 data ,无法完成删除操作,
//直接返回;
if(!find_data(pointer,data,index))
return 0;
for(int i=index;i<pointer->data_num-1;i++)
pointer->data[i]=pointer->data[i+1];
pointer->data_num --;
if(pointer->data_num>=MAX_NUM/2)
return 0;
if(pointer->is_leaf())
{
if(pointer->data_num>0)
return 0;
delete pointer;
pointer=NULL;
//子树高度发生变化;
return 1;
}
if(pointer->is_half_leaf())
{
if(pointer->data_num>0)
return 0;
t_node * tmp=pointer;
pointer=(NULL!=pointer->pleft?pointer->pleft:pointer->pright);
pointer->bf=0;
delete tmp;
return 1;
}
int min;
int flag=0;
min=remove_helper(pointer->pleft,flag);
for(int i=pointer->data_num-1;i>=0;i--)
pointer->data[i+1]=pointer->data[i];
pointer->data[0]=min;
pointer->data_num++;
int new_flag=0;
if(0==flag)
return 0;
if(pointer->bf>=0)
new_flag=0;
else
new_flag=1;
pointer->bf++;
if(pointer->bf>1)
{
if(0==pointer->pright->bf)
{
new_flag=0;
pointer=RRsingleRotation(pointer);
}
else if(1==pointer->pright->bf)
{
new_flag=1;
pointer=RRsingleRotation(pointer);
}
else
{
new_flag=1;
pointer=RLdoubleRotation(pointer);
}
}
return new_flag;
}
int t_tree::remove_helper(t_node *& pointer,int & flag)
{
int max;
if(NULL==pointer->pright)
{
max=pointer->data[pointer->data_num-1];
pointer->data_num--;
if(pointer->data_num>=MAX_NUM/2)
{
flag=0;
return max;
}
if(pointer->is_leaf())
{
if(pointer->data_num>0)
{
flag=0;
return max;
}
delete pointer;
pointer=NULL;
flag=1;
return max;
}
if(pointer->is_half_leaf())
{
if(pointer->data_num>0)
{
flag=0;
return max;
}
t_node * tmp=pointer;
pointer=(NULL!=pointer->pleft?pointer->pleft:pointer->pright);
delete tmp;
pointer->bf=0;
flag=1;
return max;
}
}
max=remove_helper(pointer->pright,flag);
//根据在子树的操作是否导致树高发生变化,
//进行调整,原理与上面提到的类似;
if(0==flag)
return max;
if(pointer->bf<=0)
flag=0;
pointer->bf--;
if(pointer->bf<-1)
{
if(0==pointer->pleft->bf)
{
flag=0;
pointer=LLsingleRotation(pointer);
}
else if(-1==pointer->pleft->bf)
{
flag=1;
pointer=LLsingleRotation(pointer);
}
else
{
flag=1;
pointer=LRdoubleRotation(pointer);
}
}
return max;
}
bool t_tree::add(int data)
{
insert(root,data);
return true;
}
bool t_tree::remove(int data)
{
remove(root,data);
return true;
}
void t_tree::display(t_node * pointer)
{
while(pointer)
{
display(pointer->pleft);
cout<<"info : data_num:"<<pointer->data_num<<" bf:"<<pointer->bf<<" node type:";
if(pointer->is_leaf())
cout<<"is_leaf"<<endl;
else if(pointer->is_half_leaf())
cout<<"is_half_leaf"<<endl;
else
{
cout<<"internal node"<<endl;
if(pointer->data_num< MAX_NUM/2)
cout<<" error : the internal node don't has enough datas"<<endl;
}
if(pointer->bf <-1 || pointer->bf>1)
cout<<"balance factor error "<<endl;
if(0==pointer->data_num)
cout<<"zero data error "<<endl;
for(int i=0;i<pointer->data_num;i++)
{
cout<<i+1<<":"<<pointer->data[i]<<" ";
}
cout<<endl;
pointer=pointer->pright;
}
}
void t_tree::deletree(t_node * pointer)
{
stack<t_node *> st;
t_node * store_right=NULL;
while(NULL!=pointer)
{
st.push(pointer);
pointer=pointer->pleft;
}
while(!st.empty())
{
pointer=st.top();
if(pointer->pright==store_right)
{
delete pointer;
store_right=pointer;
st.pop();
}
else
{
pointer=pointer->pright;
while(pointer)
{
st.push(pointer);
pointer=pointer->pleft;
}
store_right=NULL;
}
}
}
void t_tree::display()
{
display(root);
}
t_tree::~t_tree()
{
deletree(root);
}
#endif//#ifndef T_TREE_H;