实验四平衡二叉树演示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四平衡二叉树演示
1•问题定义及需求分析
课题目的和任务
问题描述:
利用平衡二叉树设计动态查找表。

\
/ 实验要求:\
设计平衡二叉树的动态演示的模拟程序。

1)采用平衡二叉树存储结构。

2)完成平衡二叉树的创建、查找、插入和删除的演示操作。

3)可以考虑两棵平衡二叉树的合并。

数据形式
输入数据形式:通过键盘输入数据
输入值的范围:树中元素的值为float型,范围为至+38;树的名称为char
类型数据,可以输入字母,数字和符号,但是长度必须在20位以
内;对菜单进行操作时,输入数据长度必须在200以内,且有效的输入
数据为0至7,其中0为退出程序,1至7为对应菜单的操作选项。

输出数据
形式:输出到显示器。

程序功能
\ 创建平衡二叉树存储结构,通过平衡因子,使二叉排序树达到平衡,提供平衡二叉树的创建、查找和删除,树中元素的查找、插入和删除等基本
功能,可以实现创建多棵平衡二叉树,并且能够进行两棵树的合并。

通过平
衡二叉树,能够使树时刻保持平衡,从而提高在树中遍历数据的速度,具有
重要意义。

测试数据
1
0 1 0 1 0 log n 0 log n
O 2n
[青输入你想要访冋的树名:
t2
t2树现在的形狀为(’〔)'里为平衛因子,7代表空儿3(-1)
1(0) 7(0)
咔+ 4(0 10(0)
请按任意犍继续・・・.
请输入你祖要访问的树名’
12
t2树现在的形状为('()'里为平術因子■ *代表空h 3M)
1(0) 4(7
* * * io to)
***□!:****
\z
衡树
"<<end
l; 2. 在树中查找元素"<<endl;
3. 在树中插入元素"<<endl;
4. 在树中删除元素"<<endl;
5. 输出二叉平衡树结构示意图"<<e ndl;
6. 合并两个二叉平衡树"<<e ndl;
7. 删除二叉平衡树"<<endl<<endl;
0退出程序):";
建二叉平
break;
}
}
switch(a){
case '1':{
system("cls");
cout<<"请输入需要创建的平衡树个数:";
int j,k;
cin> >k;
for(j=0;j<k;j++){
cout<<"请输入第"<<j+1<<"棵平衡树的树名(小于20个字符):"; char n
ame[NAME_LENGTH]; /
cin»n ame;
cout<<"请输入元素个数:"<<endl;
int m,n;
cin>>n; \ /
cout<<"请依次输入元素:"<<endl;
Type e;
AVL t=NULL;
for(m=0;m <n ;m++){
cin >>;
int taller=O;<<e ndl;
}
else{cout<<"该树中不存在这个数!"<<e ndl;}
system("pause");
system("cls");
break;
}
case 3:{
system("cls");
cout<<"请输入你想要访问的树名:"<<e ndl;
char n ame[NAME_LENGTH];
cin»n ame;
Li nk s;
if(!SearchL(l, name,s)){
cout<<"未找到该名字的平衡树!"<<e ndl;
system("pause");
system("cls");
break;
}
cout<<"请输入插入元素个数"<<e ndl;
int m,n;
cin»n;
cout<<"请依次输入插入元素"<<e ndl;
Type e;
for(m=0;m <n ;m++){
cin >>;
int taller=O;〃增高标识,1为增高,0为不增高
In sertTree(s->t,e,taller);
}
\ cout<<"插入成功!"<<endl;
system("pause");
system("cls");
break;
}
case '4':{
system("cls");
cout<<"请输入你想要访问的树名:"<<e ndl;
char n ame[NAME_LENGTH];
cin»n ame; \ /
Li nk s;
if(!SearchL(l, name,s)){
'*'代表空):
cout<<"未找到该名字的平衡树! "<<e ndl; system("pause"); system("cls"); break;
}
cout<<"请输入删除元素个数 "<<e ndl; int m,n; cin»n;
cout<<"请依次输入需要删除的元素 "<<e ndl; Type e;
for(m=0;m <n ;m++){
cin >>;
int shorter=0;〃降低表示,1为降低,0为不降低 DeleteTree(s->t,e,shorter); }
cout<<"删除成功! "<<e ndl; system("pause"); system("cls"); break; }
case '5':{
system("cls");
cout<<"请输入你想要访问的树名: "<<e ndl; char n ame[NAME_LENGTH]; cin»n ame; Li nk s;
if(!SearchL(l, name,s)){
cout<<"未找到该名字的平衡树! "<<e ndl; system("pause"); system("cls"); break;
\ }
if(s->t!=NULL){
cout<<s->tree_name<<"树现在的形状为('()'里为平衡因子, "<<e ndl;
Prin tTreeStructure(s->t); cout<<e ndl; }
system("pause"); system("cls"); break; }
case '6':{
system("cls");
"<<e ndl;
(会将后者合并到前者): cout<<"请分别输入你想要合并的两个树的名字
char n ame1[NAME_LENGTH]; cin»n amel;
Li nk s1;
if(!SearchL(l, name1,s1)){
cout<<"未找到该名字的平衡树!"<<e ndl;
system("pause");
system("cls");
break;
}
char n ame2[NAME_LENGTH];
cin»n ame2;
Li nk s2;
if(!SearchL(l, name2,s2)){
cout<<"未找到该名字的平衡树!"<<e ndl;
system("pause");
system("cls");
break;
}
else{
MergeTree(s1->t,s2->t);〃将t2 合并到t1 上DeleteL(s2);〃删除链表结点
12 cout<<"合并树成功!"<<e ndl;
system("pause"); system("cls");
break;
}
}
case '7':{
system("cls");
cout<<"请输入你想要删除的树的名字:"<<e ndl;
\ char name[NAME_LENGTH];
cin»n ame;
Li nk s;
if(!SearchL(l, name,s)){
cout<<"未找到该名字的平衡树!"<<e ndl;
system("pause");
system("cls");
break;
}
else{ \ /
DestroyTree(s->t);
DeleteL(s);
cout<<"删除树成功!"<<e ndl;
system("pause");
system("cls");
break;
}
}
}
}
}
/**/
#i nclude""
void LeftBalance(AVL& t){〃左部平衡化处理
AVL l,lr;
l=t->lchild;
switch(l->bf){
//检查T的左子树平衡度,并作相应的平衡处理case,做单右旋处理t->bf=l->bf=EH;
R_Rotate(t);
break;
case , insertAVL 用不着
t->bf=LH;
l->bf=RH;
R_Rotate(t);
break;
case,做双旋处理
lr=l->rchild;
switch(lr->bf){
case LH:
t->bf=RH;
l->bf=EH;
break;
case EH:
t->bf=l->bf=EH;
break;
case RH:
t->bf=EH;
l->bf=LH;
break;
}
lr->bf=EH; \ /
L_Rotate(t->lchild);
R_Rotate(t);
}
}
void RightBalance(AVL& t){〃右部平衡化处理
AVL r,rl;
r=t->rchild;
switch(r->bf){
case,要做单左旋处理
t->bf=r->bf=EH;
L_Rotate(t);
break;
case , insertAVL 用不着
t->bf=RH;
r->bf=LH;
L_Rotate(t);
break;
case,要做双旋处理
rl=r->lchild;
switch(rl->bf){
case LH:
t->bf=EH;
r->bf=RH;
break;
case EH:
t->bf=r->bf=EH;
break;
case RH:
t->bf=LH;
r->bf=EH;
break;
}
rl->bf=EH;
R_Rotate(t->rchild);
L_Rotate(t); \
}
}
/**/
#i nclude""
int InsertTree(AVL& t,Type e,int& taller){// 二叉平衡树的结点插入if(!t){
t=(AVL)malloc(sizeof(AVLTree)); 、、
t->=;
t->lchild=t->rchild=NULL;
0,结束
t->bf=EH;
taller=1;
}
else{
if==t->{〃找到重复元素时,不插入,返回 0
taller=0;
return 0;
}
if<t->{〃应在T 的左子树中搜寻
if(!l nsertTree(t->lchild,e,taller))return 0;// 找到重复元素,依次返回
if(taller){〃插入左子树,且左子树变高
switch(t->bf){
case ,需要做左平衡处理
LeftBala nce(t);
taller=0;
break;
case ,现因左子树增高而树增高
t->bf=LH;
taller=1;
break;
case ,现在左右子树等高
t->bf=EH;
taller=0;
break;
"/switch
}//if
}//if
else{//应在T 的右子树中搜寻
if(!InsertTree(t->rchild,e,taller))returin 0; if(taller){//插入右子树,且右子树长高 switch(t->bf){
case ,现在左右子树等高
t->bf=EH;
taller=0;
break;
case ,现在右子树变高
t->bf=RH;
taller=1;
break;
case ,现在需做右平衡处理
RightBala nce(t);
taller=0;
break;
}//switch
即查找q
}//if
}//else
}//else
return 1;
}
/**/
#i nclude""
int DeleteTree(AVL& t,Type e,int& shorter){〃 平衡二叉树的结点删除
if(t==NULL){〃不存在该元素
return 0;//删除失败
}
else if==t->{//找到元素结点 \
AVL q=NULL;
if(t->lchild==NULL){// 左子树为空
q=t;
t=t->rchild;
delete q;
shorter=1;
}
else if(t->rchild==NULL){// 右子树为空
q=t;
t=t->lchild;
delete q;
shorter=1;
}
else{//左右子树都存在
q=t->lchild;
\ while(q->rchild){//找到要删除结点t 的左孩子的最右孩子 q
q=q->rchild;
}
t->=q->;//把q 的值给t
DeleteTree(t->lchild,q->data,shorter);// 在左子树中递归删除前驱结点。

的值
if(shorter){
switch(t->bf){
case LH:
t->bf=EH;
shorter=1;
break;
case EH: t->bf=RH; \ /
shorter=0;
break;
if(t->rchild->bf==EH)
shorter=0;
else
shorter=1;
RightBalance(t);〃右平衡处理break;
}
}
}
}
else if<t->{〃左子树中继续查找if(!DeleteTree(t->lchild,e,shorter)){ return 0;
}
if(shorter){ switch(t->bf){ case LH:
t->bf=EH;
shorter=1;
break;
case EH:
t->bf=RH;
shorter=0;
break;
case RH:
if(t->rchild->bf==EH)
shorter=0;
else
shorter=1;
\ RightBalance(t);〃右平衡处理
break;
}
}
}
else{//右子树中继续查找
if(!DeleteTree(t->rchild,e,shorter)){ return 0;
}
if(shorter){ switch(t->bf){
case LH: \ /
if(t->lchild->bf==EH)
shorter=0;
else
shorter=1;
LeftBalance(t); // 左平衡处理break;
case EH:
t->bf=LH;
break;
case RH:
/ t->bf=EH;
shorter=1;
break;
}
}
}
return 1;
}
/**/
#i nclude""
int DestroyTree(AVL& t){〃递归销毁二叉平衡树if(t==NULL){
return 0;
}
DestroyTree(t->lchild);
DestroyTree(t->rchild);
free(t);
return 1;
}
/**/
#i nclude""
int InitL(Link& l){//创建含一个空头结点的双向链表if(!(l=(L in
k)malloc(sizeof(LNode))))return 0; l->prior=l->n ext=NULL;
l->t=NULL;
return 1;
}
int InsertL(Link& l,AVL& t,char* name){〃在双向链表中插入元素Li nk p; \ / p=(L in k)malloc(sizeof(LNode));
p->t=t;
成功则获取该链表结点的地 strcpy(p->tree_name,name);// 将平衡树的树名保存
p->n ext=l->n ext;
if(l->n ext!=NULL)l->n ext->prior=p;
l->n ext=p;
p->prior=l;
return 1;
}
con st int SearchL(L ink l,char* name,L ink& s){// 在链表中查询树名, 址,返回true
l=l->n ext;
while(l!=NULL){
if(strcmp(l->tree _n ame, name)==0){
s=l;
return 1;
}
l=l->n ext;
}
return 0;
}
int DeleteL(Link& l){//在链表中删除I 结点
if(l-> next==NULL){
l->prior- >n ext=NULL;
free(l);
}
else{
l->prior- >n ext=l->n ext;
l->n ext->prior=l->prior; free(l);
}
return 1;
}
/**/
#i nclude""
int MergeTree(AVL& t1,AVL& t2){// 将树 t2 合并到 t1 上 while(t2!=NULL){
int taller,shorter;
In sertTree(t1,t2->data,taller);
DeleteTree(t2,t2->data,shorter);
}
}
/**/
#i nclude""
con st int Prin tTreeStructure(AVL t){〃利用层次遍历,输出树的形状
if(!t){return 0;}
int i=0,level=0,j, num;
Li nkQ q;
Ini tQ(q);
while(1){
i++;
num=0;
j=1; \
while(j<=i){
num++;〃num为记层标志,记录当前T所在层数
j=2*j;
}
if(t!=NULL){
cout<<t-x<"("<<t->bf<<")";
En Q(q,t->lchild);
En Q(q,t->rchild);
if(j==i+1){
cout<<e ndl;
}
if(t->lchild==NULL&&t->rchild==NULL){//T 为空时进行判断,当平衡树中出现层数不同的空结点时,终止输出
if(!level){//首次出现两个孩子都空的结点,将其孩子的层数赋给level
level=nu m+1;
\ }
}
}
else{
En Q(q,NULL);//若该点为空,则它的孩子也为空,入队列
En Q(q,NULL);
if(level&&I evel+2==num){
return 1;
}
else{cout<<"* ";}// 用* 代表空
if(j==i+1){
cout<<e ndl;
}
}
DeQ(q,t);
}//while
}
/**/
#i nclude ""
int InitQ(LinkQ& q){〃创建空队列==(QP)malloc(sizeof(QNode));
if(!return 0;
>n ext=NULL;
return 1;
}
int EnQ(LinkQ& q,AVL e){// 入队列
QP p;
p=(QP)malloc(sizeof(QNode));
if(!p)return 0;
p->tree=e;
p-> next=NULL;
>n ext=p;
=p;
return 1;
}
int DeQ(LinkQ& q,AVL& e){// 出队列
if==return 0;
QP p;
p=>n ext;
e=p->tree;
>n ext=p->n ext;
if==p)=;
free(p);
return 1;
}
/**/ \
#i nclude""
void R_Rotate(AVL& t){//以T为根节点的二叉排序树进行右旋转AVL l; l=t->lchild;
t->lchild=l->rchild;
l->rchild=t;
t=l;//p指向新的根节点
}
void L_Rotate(AVL& t){//以T为根节点的二叉排序树进行左旋转
AVL r;
r=t->rchild;
t->rchild=r->lchild;
r->lchild=t;
t=r;
}
/**/
#i nclude""
con st int SearchTree(AVL t,Type key,AVL & p){//搜索树中是否包含该元素while(t){ if==t->{p=t;return 1;}
else if<t->{
p=t;
t=t->lchild;
}
else{
p=t;
t=t->rchild;
}
}
return 0;
}。

相关文档
最新文档