平衡二叉树.docx

上传人:b****7 文档编号:10247287 上传时间:2023-02-09 格式:DOCX 页数:22 大小:65.16KB
下载 相关 举报
平衡二叉树.docx_第1页
第1页 / 共22页
平衡二叉树.docx_第2页
第2页 / 共22页
平衡二叉树.docx_第3页
第3页 / 共22页
平衡二叉树.docx_第4页
第4页 / 共22页
平衡二叉树.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

平衡二叉树.docx

《平衡二叉树.docx》由会员分享,可在线阅读,更多相关《平衡二叉树.docx(22页珍藏版)》请在冰豆网上搜索。

平衡二叉树.docx

平衡二叉树

一、问题描述:

建立一个平衡二叉树,要求做增删查改的操作

二、概要设计

定义一个节点存贮结构,包含权值以及平衡因子的值,平衡因子的值的绝对值为<=1时,则为平衡,否则需要调平,多种调平动作

三、详细设计

弄清楚增加节点和删除节点的情况,分情况讨论要求将所有的情况考虑进去然后根据最基本的四种结构左左右右左右右左进行调平

四、测试及结果

五、心得体会

通过这次试验我明白了两种算法的差异以及实现的机制,算法之巧妙着实让我弄了很长一段时间

源代码清单

Function.cpp

#include"stdafx.h"

#include"function.h"

//创建二叉树以-32767结束

voidCreatBT(BTree&T)

{

intm;

inti;

booltaller=false;

T=NULL;//初始化树为空

cout<<"请输入关键字(且以-32767为结束建立二叉树):

"<

cin>>i;

getchar();

while(i!

=-32767)

{

InsertBT(T,i,taller);

cout<<"请输入关键字(以-32767结束创建二叉树):

"<

cin>>i;

getchar();

taller=false;

}

m=0;

cout<<"您创建的二叉树为:

"<

PrintBT(T,m);

}

//直接创建平衡二叉树

voidCreat_AVL(BTree&T)

{

intm;

inti;

booltaller=false;

T=NULL;

cout<<"请输入关键字(以-32767结束建立平衡二叉树):

"<

scanf("%d",&i);

getchar();

while(i!

=-32767)

{

SetAVL(T,i,taller);

cout<<"请输入关键字(以-32767结束建立平衡二叉树):

"<

cin>>i;

getchar();

taller=false;

}

m=0;

cout<<"平衡二叉树创建结束."<

if(T)

PrintBT(T,m);

else

cout<<"这是一棵空树."<

}

//将二叉树打印出来

voidPrintBT(BTreeT,intm)

{

if(T)//当树不为空时

{

inti;

if(T->rchild)

{

PrintBT(T->rchild,m+1);

}

for(i=1;i<=m;i++)

cout<<"";//打印i个空格用来表示出层次

cout<data<

if(T->lchild)

PrintBT(T->lchild,m+1);

}

}

//对*p为根的进行右旋转处理

voidRight_Balance(BTree&p)

{

BTreelc;

lc=p->lchild;//lc指向的*p左子树根结点

p->lchild=lc->rchild;//lc的右子树挂接为*p的左子树

lc->rchild=p;

p=lc;//p指向新的结点

}

//对以*p为根的二叉排序树作左旋处理

voidLeft_Balance(BTree&p)

{

BTreerc;

rc=p->rchild;//指向的*p右子树根结点

p->rchild=rc->lchild;//rc左子树挂接到*p的右子树

rc->lchild=p;

p=rc;//p指向新的结点

}

//对以指针T所指结点为根的二叉树作左平衡旋转处理

voidLeft_Root_Balance(BTree&T)//左左型和左右型

{

BTreelc,rd;

lc=T->lchild;//指向*T的左子树根结点

switch(lc->bf)//检查*T的左子树的平衡度,并作相应平衡处理

{

caseLH:

//新结点插入在*T的左孩子的左子树上,要作单右旋处理

T->bf=lc->bf=EH;

Right_Balance(T);

break;

caseRH:

//新结点插入在*T的左孩子的右子树上,要作双旋处理

rd=lc->rchild;//rd指向*T的左孩子的右子树根

switch(rd->bf)//修改*T及其左孩子的平衡因子

{

caseLH:

T->bf=RH;

lc->bf=EH;

break;

caseEH:

T->bf=lc->bf=EH;

break;

caseRH:

T->bf=EH;

lc->bf=LH;

break;

}

rd->bf=EH;

Left_Balance(T->lchild);//对*T的左子树作左旋平衡处理

Right_Balance(T);//对*T作右旋平衡处理

}

}

//对以指针T所指结点为根的二叉树作右平衡旋转处理

voidRight_Root_Balance(BTree&T)

{

BTreerc,ld;

rc=T->rchild;//指向*T的右子树的根节点

switch(rc->bf)

{

caseRH:

//新节点插在*T

T->bf=rc->bf=EH;

Left_Balance(T);

break;

caseLH:

ld=rc->lchild;//ld指向*T的右孩子的左子树根

switch(ld->bf)

{

caseLH:

T->bf=EH;

rc->bf=RH;

break;

caseEH:

T->bf=rc->bf=EH;

break;

caseRH:

T->bf=LH;

rc->bf=EH;

break;

}

ld->bf=EH;

Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理

Left_Balance(T);//对*T作左旋平衡处理

}

}

//插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0

boolInsertBT(BTree&T,inti,bool&taller)

{

if(!

T)//插入新结点,树“长高”,置taller为true

{

T=(BTree)malloc(sizeof(BTNode));

T->data=i;

T->lchild=T->rchild=NULL;

T->bf=EH;//置平衡因子为零

taller=true;

}

else

{

if(ET(i,T->data))//树中已存在和有相同关键字的结点是否i==T->data

{

taller=false;//将taller置为false表示插入失败

cout<<"已存在相同关键字的结点"<

return0;

}

if(LT(i,T->data))//应继续在*T的左子树中进行搜索

{

if(!

InsertBT(T->lchild,i,taller))

return0;

}

else//应继续在*T的右子树中进行搜索

{

if(!

InsertBT(T->rchild,i,taller))

return0;

}

}

return1;

}

/*删除结点时左平衡旋转处理*/

voidLeft_Root_Balance_det(BTree&p,int&shorter)

{

BTreep1,p2;

if(p->bf==1)//p结点的左子树高,删除结点后p的bf减,树变矮

{

p->bf=0;

shorter=1;

}

elseif(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变

{

p->bf=-1;

shorter=0;

}

else//p结点的右子树高

{

p1=p->rchild;//p1指向p的右子树

if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变

{

Left_Balance(p);

p1->bf=1;

p->bf=-1;

shorter=0;

}

elseif(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮

{

Left_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else//p1的左子树高,进行双旋处理(先右旋后左旋),树变矮

{

p2=p1->lchild;

p1->lchild=p2->rchild;

p2->rchild=p1;

p->rchild=p2->lchild;

p2->lchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

elseif(p2->bf==-1)

{

p->bf=1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=-1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

 

/*删除结点时右平衡旋转处理*/

voidRight_Root_Balance_det(BTree&p,int&shorter)

{

BTreep1,p2;

if(p->bf==-1)

{

p->bf=0;

shorter=1;

}

elseif(p->bf==0)

{

p->bf=1;

shorter=0;

}

else

{

p1=p->lchild;

if(p1->bf==0)

{

Right_Balance(p);

p1->bf=-1;

p->bf=1;

shorter=0;

}

elseif(p1->bf==1)

{

Right_Balance(p);

p1->bf=p->bf=0;

shorter=1;

}

else

{

p2=p1->rchild;

p1->rchild=p2->lchild;

p2->lchild=p1;

p->lchild=p2->rchild;

p2->rchild=p;

if(p2->bf==0)

{

p->bf=0;

p1->bf=0;

}

elseif(p2->bf==1)

{

p->bf=-1;

p1->bf=0;

}

else

{

p->bf=0;

p1->bf=1;

}

p2->bf=0;

p=p2;

shorter=1;

}

}

}

 

/*删除结点*/

voidDelete(BTreeq,BTree&r,int&shorter)

{

if(r->rchild==NULL)

{

q->data=r->data;

q=r;

r=r->lchild;

free(q);

shorter=1;

}

else

{

Delete(q,r->rchild,shorter);

if(shorter==1)

Right_Root_Balance_det(r,shorter);

}

}

/*二叉树的删除操作*/

intDeleteAVL(BTree&p,intx,int&shorter)

{

intk;

BTreeq;

if(p==NULL)

{

cout<<"不存在要删除的关键字!

!

"<

return0;

}

elseif(xdata)//在p的左子树中进行删除

{

k=DeleteAVL(p->lchild,x,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

returnk;

}

elseif(x>p->data)//在p的右子树中进行删除

{

k=DeleteAVL(p->rchild,x,shorter);

if(shorter==1)

Right_Root_Balance_det(p,shorter);

returnk;

}

else

{

q=p;

if(p->rchild==NULL)//右子树空则只需重接它的左子树

{

p=p->lchild;

free(q);

shorter=1;

}

elseif(p->lchild==NULL)//左子树空则只需重接它的右子树

{

p=p->rchild;

free(q);

shorter=1;

}

else//左右子树均不空

{

Delete(q,q->lchild,shorter);

if(shorter==1)

Left_Root_Balance_det(p,shorter);

p=q;

}

return1;

}

}

/*调平二叉树具体方法*/

boolSetAVL(BTree&T,inti,bool&taller)

{

if(!

T)//插入新结点,树“长高”,置taller为true

{

T=(BTree)malloc(sizeof(BTNode));

T->data=i;

T->lchild=T->rchild=NULL;

T->bf=EH;

taller=true;

}

else

{

if(ET(i,T->data))//树中已存在和有相同关键字的结点

{

taller=false;

cout<<"已存在相同关键字的结点"<

return0;

}

if(LT(i,T->data))//应继续在*T的左子树中进行搜索

{

if(!

SetAVL(T->lchild,i,taller))

return0;

if(taller)//已插入到*T的左子树中且左子树“长高”

switch(T->bf)//检查*T的平衡度

{

caseLH:

//原本左子树比右子树高,需要作左平衡处理

Left_Root_Balance(T);

taller=false;

break;

caseEH:

//原本左子树、右子等高,现因左子树增高而使树增高

T->bf=LH;

taller=true;

break;

caseRH:

//原本右子树比左子树高,现左、右子树等高

T->bf=EH;

taller=false;

break;

}

}

else//应继续在*T的右子树中进行搜索

{

if(!

SetAVL(T->rchild,i,taller))

return0;

if(taller)//已插入到*T的右子树中且右子树“长高”

switch(T->bf)//检查*T的平衡度

{

caseLH:

//原本左子树比右子树高,现左、右子树等高

T->bf=EH;

taller=false;

break;

caseEH:

//原本左子树、右子等高,现因右子树增高而使树增高

T->bf=RH;

taller=true;

break;

caseRH:

//原本右子树比左子树高,需要作右平衡处理

Right_Root_Balance(T);

taller=false;

break;

}

}

return1;

}

}

Main函数:

//平衡二叉树.cpp:

定义控制台应用程序的入口点。

//

#include"stdafx.h"

#include"function.h"

 

int_tmain(intargc,_TCHAR*argv[])

{

system("color9f");

system("modecon:

cols=100lines=40");

intinput,m;

charsearch;

booltaller=false;

intshorter=0;

BTreeT;

T=(BTree)malloc(sizeof(BTNode));

T=NULL;

while

(1)

{

cout<<"\n请选择需要的二叉树操作\n"<

cout<<"1.创建二叉树.增加新结点.直接创建平衡二叉树.在平衡二叉树上增加新结点并调平衡.删除.退出\n"<

cin>>input;

getchar();

switch(input)

{

case1:

CreatBT(T);

break;

case2:

cout<<"请输入你要增加的关键字"<

cin>>search;

getchar();

InsertBT(T,search,taller);

m=0;

PrintBT(T,m);

break;

case3:

Creat_AVL(T);

break;

case4:

cout<<"请输入你要增加的关键字"<

cout<

getchar();

SetAVL(T,search,taller);

m=0;

PrintBT(T,m);

break;

case5:

cout<<"请输入你要删除的关键字";

scanf("%d",&search);

getchar();

DeleteAVL(T,search,shorter);

m=0;

PrintBT(T,m);

break;

case0:

break;

default:

cout<<"输入错误,请重新选择。

";

break;

}

if(input==0)

break;

cout<<"按任意键继续.";

getchar();

}

return0;

}

Function.h

#include

#include

#include

usingnamespacestd;

//定义树的结点类型

typedefstructBTNode

{

intdata;

intbf;//平衡因子

structBTNode*lchild,*rchild;//左、右孩子

}BTNode,*BTree;

#defineLH+1//LeftHeight左高

#defineEH0//EqualHeight相同的高度

#defineRH-1//RightHeightHigh右高

#defineET(a,b)((a)==(b))//a=b

#defineLT(a,b)((a)<(b))//a

#defineRT(a,b)((a)>(b))//a>b

//需要的函数声明

voidCreatBT(BTree&T);//创建二叉树以#结束

voidRight_Balance(BTree&p);//对*p为根进行右旋转处理

voidLeft_Balance(BTree&p);//对*p为根的进行左旋转处理

voidLeft_Root_Balance(BTree&T);//对*T所指节点为根的二叉树作左旋转调平

voidRight_Root_Balance(BTree&T);//对*T所指结点为根的二叉树作右旋转调平

boolInsertBT(BTree&T,inti,bool&taller);//插入节点,若结点中存在该点则返回值为否则的话voidDelete(BTreeq,BTree&r,int&shorter);//删除某个节点

voidLeft_Root_Balance_det(BTree&p,int&shorter);//删除某个节点进行平衡二叉树左平衡转

voidRight_Root_Balance_det(BTree&p,int&shorter);//删除某个节点进行平衡二叉树右平衡调

intDeleteAVL(BTree&p,intx,int&shorter);//删除整个二叉树

voidCreat_AVL(BTree&T);//直接创建平衡二叉树

boolSetAVL(BTree&T,inti,bool&taller);//二叉树的调平情况分类进行调平函数

voidPrintBT(BTreeT,i

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1