T tree c++实现源代码(二)

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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值