码迷,mamicode.com
首页 > 编程语言 > 详细

二叉平衡排序树的基本操作

时间:2016-05-07 06:35:48      阅读:320      评论:0      收藏:0      [点我收藏+]

标签:

//定义数据类型
 
#define  MAXSIZE = 100;
#define OK  1;
#define ERROR 0;
 
typedef int status;
typedef int ElemType;
 
//平衡二叉排序树的结构
typedef struct Tnode
{
ElemType data;
struct Tnode *lchild,*rchild;
int height;          //以该节点为根的子树的高度
}BBTnode,*BBTree;
 
typedef BBTree Position;
//栈定义
typedef struct
{
BBTree *base,*top;    //栈指针成员
int initsize;        //栈初始长度
}Stack;
 
 
//队列定义
typedef struct
{
BBTree *front,*rear;  //队列指针成员
int InitSize;        //栈初始长度
}Queue;
----------------------------------------------------------------------------------
插入和删除节点
 
//插入节点函数
status InsertBBT(BBTree &T,ElemType e)  //插入新结点
{
if(T == NULL)     //空树,建一个节点给树
{
T = (BBTree)malloc(sizeof(BBTnode));
if(!T) return ERROR;
T->data = e;
T->lchild = T->rchild = NULL;
T->height = 0;
}
else if(e < T->data)  //向左插入
{
InsertBBT(T->lchild,e);
if(Height(T->lchild) - Height(T->rchild) == 2)  //出现不平衡了
{
//如果用序列(5,2,1...)就可会出现LL型,用序列(5,2,3...)就可会出现LR型
if(e < T->lchild->data)  //这样对应于 LL 型
T = LL_SingleRotate(T);
else             //这个对应于 LR 型
T = LR_DoubleRotate(T);
}
}
else if(e > T->data)  //向右插入
{
InsertBBT(T->rchild,e);
if(Height(T->rchild) - Height(T->lchild) == 2)  //出现不平衡了
{
//如果用序列(5,6,7...)就可会出现RR型,用序列(5,7,6...)就可会出现RL型
if(e > T->rchild->data)  //这样对应于 RR 型
T = RR_SingleRotate(T);
else           //这样对应于 RL 型
T = RL_DoubleRotate(T);
}
}
//如果 e == T->data 的话什么也不干,最后要记录T->height
T->height = Max(Height(T->lchild),Height(T->rchild)) + 1;
return OK;
}
 
//删除节点函数
status DeleteBBT(BBTree &T,ElemType e)             //删除某结点
{
Position temp;
 
if(T == NULL) return ERROR;
else if(e < T->data)
return DeleteBBT(T->lchild,e);
else if(e > T->data)
return DeleteBBT(T->rchild,e);
else   //即 e == T->data的情况
{
if(T->lchild != NULL && T->rchild !=NULL)    //有两个孩子
{
temp = FindMax(T->lchild);   //在右子树中找到最小的节点
T->data = temp->data;  //用找到的最小节点的data代替要删除节点的data
DeleteBBT(T->lchild,T->data);  //删除右边刚刚找出的最小的节点
}
else    //有一个或者没有孩子
{
temp = T;
if(T->lchild == NULL)   //也处理了0个孩子的情况
T = T->rchild;
else if(T->rchild == NULL)
T = T->lchild;
free(temp);
}
return OK;
}
}
 
//找最大的Element
Position FindMax(BBTree T)          
{
if(T == NULL) return NULL;
else if(T->rchild == NULL) return T;
else return FindMax(T->rchild);
}
 
//求较大的数
int Max(int l,int r)      
{
return l>r?l:r;
}
 
 
//求树的高度
int Height(BBTree T)        
{
if(T == NULL) return -1;
else return T->height;
}
 
 //向左旋转一次,抓住k1(小的),让重力话事
BBTree LL_SingleRotate(BBTree k2)   
{
BBTree k1;
k1 = k2->lchild;
k2->lchild = k1->rchild;
k1->rchild = k2;
 
k1->height = Max(Height(k1->lchild),k2->height) + 1;
k2->height = Max(Height(k2->lchild),Height(k2->rchild)) +1;
return k1;  //新的root
}
 
 //向右旋转一次,抓住k2(大的),让重力话事
BBTree RR_SingleRotate(BBTree k1)   
{
BBTree k2;
k2 = k1->rchild;
k1->rchild = k2->lchild;
k2->lchild = k1;
 
k1->height = Max(Height(k1->lchild),Height(k1->rchild)) +1;
k2->height = Max(Height(k1->rchild),k1->height) + 1;
return k2;  //新的root
}
 
 //向左转一次,向右转一次
BBTree LR_DoubleRotate(BBTree k3)   
{
k3->lchild = RR_SingleRotate(k3->lchild);  //先逆时针转
 
return LL_SingleRotate(k3);               //再顺时针转
}
 
//向右转一次,向左转一次
BBTree RL_DoubleRotate(BBTree k1)   
{
k1->rchild = LL_SingleRotate(k1->rchild);  //先顺时针转
 
return RR_SingleRotate(k1);                //再逆时针转
 
--------------------------------------------------------------------------------
 遍历
 
//递归前序遍历
status FirstViewRoot(BBTree T)       
{
if(T != NULL)
{
cout << T->data << " ";
FirstViewRoot(T->lchild);
FirstViewRoot(T->rchild);
}
return OK;
}
 
//递归中序遍历
status MiddleViewRoot(BBTree T)      
{
if(T != NULL)
{
MiddleViewRoot(T->lchild);
cout << T->data << " ";
MiddleViewRoot(T->rchild);
}
return OK;
}
 
 //递归后序遍历
status LastViewRoot(BBTree T)      
{
if(T != NULL)
{
LastViewRoot(T->lchild);
LastViewRoot(T->rchild);
cout << T->data << " ";
}
return OK;
}
 
 //非递归前序遍历
status NonFirstView(BBTree T,Stack S)       
{
while(S.base != S.top || T != NULL)
{
while(T != NULL)        //向左走到最左
{
cout << T->data << " ";   //输出元素
*S.top++ = T;
T = T->lchild;
}
T=*--S.top;   //出栈
T = T->rchild;      //转向右
}
return OK;
}
 
 //非递归中序遍历
status NonMiddleView(BBTree T,Stack S)      
{
while(S.base != S.top || T != NULL)
{
while(T != NULL)        //向左走到最左
{
*S.top++ = T;
T = T->lchild;
}
T=*--S.top;   //出栈
cout << T->data << " ";   //输出元素
T = T->rchild;      //转向右
}
return OK;
}
 
//非递归后序遍历
status NonLastView(BBTree T,Stack S)
{
BBTree pre = NULL;   //pre用来标记刚刚访问过的节点
while(S.base != S.top || T != NULL)
{
while(T != NULL)        //向左走到最左
{
*S.top++ = T;
T = T->lchild;
}
T=*(S.top - 1);   //取栈顶节点
if(T->rchild == NULL || T->rchild == pre)  //如果T没有右孩子或者其右孩子刚刚被访问过
{
cout << T->data << " ";   //输出元素
S.top--;      //已访问,令其出栈
pre = T;     //标记为刚刚访问过了
T = NULL;//这步是假设已经遍历完以这个节点为root的子树,如果栈空则真的完了,没有则没有完,会继续
}
else
T = T->rchild;      //转向右
}
return OK;
}
 
 //层次遍历
status LevelView(BBTree T,Queue Q)         
{
if(T != NULL)
{
*Q.rear++ = T;
while(Q.front != Q.rear)  //队列不空时
{
if(T->lchild != NULL) *Q.rear++ = T->lchild;  //左子树进队
if(T->rchild != NULL) *Q.rear++ = T->rchild;  //右子树进队
T = *Q.front++;       //出队
cout << T->data << " ";
T = *Q.front;         //最新的队头
}
}
return OK;
}
 
---------------------------------------------------------------------------
在二叉树中查找给定关键字
 
//(函数返回值为成功1,失败0)
status FindKeyword(BBTree T,ElemType e) 
{
if(T!=NULL)
  {
if(e == T->data) return OK;
else if(e < T->data)  return FindKeyword(T->lchild,e);
else  return FindKeyword(T->rchild,e);
  }
else return ERROR;
}
 
-------------------------------------------------------------------------------
交换各结点的左右子树
 
status SwapSubtree(BBTree T) 
{
BBTree tmpNode;
if(T != NULL)
{
tmpNode = T->lchild;
T->lchild = T->rchild;
T->rchild = tmpNode;
SwapSubtree(T->lchild);
SwapSubtree(T->rchild);
}
return OK;
}
-------------------------------------------------------------------------------
求平衡二叉树的深度、节点总数,叶子节点数
 
 //求二叉树的深度
int DeepOfTree(BBTree T)          
{
int deep,ldeep = 0,rdeep = 0;
if(T != NULL)
{
ldeep = DeepOfTree(T->lchild);
rdeep = DeepOfTree(T->rchild);
deep = Max(ldeep,rdeep) + 1;
}
else return 0;
return deep;
}
 
  //总的结点数
int TotalNodeNumber(BBTree T)            
{
int sum = 0,lsum = 0,rsum = 0;
if(T != NULL)
{
lsum = TotalNodeNumber(T->lchild);
rsum = TotalNodeNumber(T->rchild);
sum = lsum + rsum + 1;
return sum;
}
else return 0;
}
 
//叶子结点数
int LeafNodeNumber(BBTree T)        
{
int cnt = 0,lcnt = 0,rcnt = 0;
if(T != NULL)
{
if(T->lchild == NULL && T->rchild == NULL) cnt=1;
else
{
lcnt = LeafNodeNumber(T->lchild);
rcnt = LeafNodeNumber(T->rchild);
cnt = lcnt + rcnt;
}
}
else return 0;
return cnt;
}

二叉平衡排序树的基本操作

标签:

原文地址:http://www.cnblogs.com/yujon/p/5467613.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!