平衡二叉排序树

来源:互联网 发布:mac怎样安装字体 编辑:程序博客网 时间:2024/04/28 12:11
#include<iostream>using namespace std;#define LH 1//左高#define EH 0//等高#define RH -1//右高typedef  int Status;template<class U>class BSTNode{public:template<class U> friend class BBSTree;private:U key;//关键字int bf;//平衡因子BSTNode *lchild ,*rchild;};template<class U>class BBSTree:public BSTNode<U>{public:void LL_Rotate(BSTNode<U> *&p);//LL型调整,即单向右旋平衡处理void RR_Rotate(BSTNode<U> *&p);//RR型调整,即单向左旋平衡处理//若在平衡的二叉排序树T中不存在和key相等的关键字的结点,则插入一个新的数据元素key//并返回1,否则返回0。若因插入而使二叉排序树失去平衡,则作平衡旋转处理,布尔变量//taller反映T长高与否Status InsertAVL(BSTNode<U> *&T,U key,bool &taller);void LeftBalance(BSTNode<U> *&T);//左旋转平衡处理void RightBalance(BSTNode<U> *&T);//右旋转平衡处理void PreOrderTraverse(BSTNode<U> *T);//前序遍历平衡二叉排序树void visit(U key);             //visit函数用于输出结点元素};template<class U>void BBSTree<U>::LL_Rotate(BSTNode<U> *&p){//对以*p为根结点的二叉排序树作单向右旋平衡处理,处理之后*p指向新的根结点,//即旋转之前左子树的根结点BSTNode<U> *lc=NULL;lc=p->lchild;//lc指向左子树根结点p->lchild=lc->rchild;//lc的右子树挂在p的左子树上lc->rchild=p;//结点p成为lc的右孩子p=lc;//p指向新的根结点}//LL_Rotatetemplate<class U>void BBSTree<U>::RR_Rotate(BSTNode<U> *&p){//对以*p为根结点的二叉排序树作单向左旋平衡处理,处理之后*p指向新的根结点,//即旋转之前右子树的根结点BSTNode<U> *lc=NULL;lc=p->rchild;//lc指向右子树根结点p->rchild=lc->lchild;//lc的左子树挂在p的右子树lc->lchild=p;//p成为lc的右孩子p=lc;//p指向新的根结点}//RR_Rotatetemplate<class U>Status BBSTree<U>::InsertAVL(BSTNode<U> *&T,U key,bool &taller){if(!T)//T不存在,插入结点为树的根结点,树长高,置taller变为true{T=new BSTNode<U>;T->key=key;T->bf=EH;//只有一个根结点,平衡因子bf为0taller=true;//树的深度加1T->lchild=NULL; T->rchild=NULL;return 1;}else{if(key==T->key)//树中已存在和e有相同关键字的结点{taller=false; return 0;}//则不再插入if(key<T->key)//关键字key小于树根结点的关键字,在树的左子树中查找{if(!InsertAVL(T->lchild,key,taller))return 0;//结点未插入if(taller)//结点插入到T的左子树中,且左子树的深度增加{switch(T->bf)//检查T的平衡度{case LH://原本左子树高于右子树,现左子树深度+1,则平衡被打破,需做平衡处理LeftBalance(T); taller=false; break;case EH://原本左、右子树等高,现左子树深度+1,则根结点T的bf加1,T长高T->bf=LH; taller=true; break;case RH://原本左子树低于右子树,现左子树深度+1,则根结点T的bf变为0,T高度不变T->bf=EH; taller=false; break;}//switch}//if}//ifelse{if(!InsertAVL(T->rchild,key,taller))//右子树中未插入return 0;if(taller){switch(T->bf)//检查T的平衡度{case LH://原本左子树高于右子树,现右子树深度+1,则根结点T的bf变为0,T高度不变T->bf=EH; taller=false; break;case EH://原本左、右子树等高,现右子树深度+1,则根结点T的bf加1,T长高T->bf=RH; taller=true; break;case RH://原本左子树低于右子树,现右子树深度+1,则平衡被打破,需做平衡处理RightBalance(T); taller=false; break;}//switch}//if}//else}//elsereturn 1;}//InsertAVLtemplate<class U>void BBSTree<U>::LeftBalance(BSTNode<U> *&T){BSTNode<U> *lc=T->lchild,*rd=NULL;//lc指向T的左子树的根结点switch(lc->bf)//检查T的左子树的平衡度,并作相应的平衡处理{case LH://左子树bf为1,新插入的结点在左孩子的左子树上进行LL型调整T->bf=EH;lc->bf=EH;//调整T和T的左子树的bf=0LL_Rotate(T);break;case RH://左子树bf为-1,新插入的结点在左孩子的右子树上进行LR型调整rd=lc->rchild;//rd指向T的左孩子的右子树根switch(rd->bf)//修改T及其左孩子的平衡因子{case LH:T->bf=RH; lc->bf=EH;break;case EH:T->bf=EH; lc->bf=EH;break;case RH:T->bf=EH; lc->bf=LH;break;}//switchrd->bf=EH;RR_Rotate(T->lchild);//对T的左子树进行左旋平衡LL_Rotate(T);//对T进行右旋平衡}//switch}//LeftBalancetemplate<class U>void BBSTree<U>::RightBalance(BSTNode<U> *&T){BSTNode<U> *lc=T->rchild ,*ld=NULL;//lc指向T的右子树的根结点switch(lc->bf)//检查T的右子树的平衡度,并作相应的平衡处理{case RH://右子树bf为-1,新插入的结点在右孩子的右子树上进行RR型调整T->bf=EH;lc->bf=EH;//调整T和T的左子树的bf=0RR_Rotate(T);break;case LH://右子树bf为1,新插入的结点在右孩子的左子树上进行LR型调整ld=lc->lchild;//rd指向T的右孩子的左子树根switch(ld->bf)//修改T及其右孩子的平衡因子{case LH:T->bf=EH; lc->bf=RH;break;case EH:T->bf=EH; lc->bf=EH;break;case RH:T->bf=LH; lc->bf=EH;break;}//switchld->bf=EH;LL_Rotate(T->rchild);//对T的左子树进行左旋平衡RR_Rotate(T);//对T进行右旋平衡}//switch}//RightBalancetemplate<class U>void BBSTree<U>::PreOrderTraverse(BSTNode<U> *T){if(T)   //平衡二叉排序树存在      {          visit(T->key);                  //访问根结点          PreOrderTraverse(T->lchild); //先序遍历左子树          PreOrderTraverse(T->rchild); //先序遍历右子树      }//if}//PreOrderTraversetemplate<class U>void BBSTree<U>::visit(U key){cout<<key<<" ";}//visitvoid main(){BBSTree<int> BBST;BSTNode<int> *T=NULL;int key;bool taller;while(cin>>key){BBST.InsertAVL(T,key,taller);}//whileBBST.PreOrderTraverse(T);}//main

0 0
原创粉丝点击