实验四 平衡二叉树演示.docx
- 文档编号:24617641
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:26
- 大小:146.07KB
实验四 平衡二叉树演示.docx
《实验四 平衡二叉树演示.docx》由会员分享,可在线阅读,更多相关《实验四 平衡二叉树演示.docx(26页珍藏版)》请在冰豆网上搜索。
实验四平衡二叉树演示
实验四平衡二叉树演示
1.问题定义及需求分析
课题目的和任务
问题描述:
利用平衡二叉树设计动态查找表。
实验要求:
设计平衡二叉树的动态演示的模拟程序。
1)采用平衡二叉树存储结构。
2)完成平衡二叉树的创建、查找、插入和删除的演示操作。
3)可以考虑两棵平衡二叉树的合并。
数据形式
输入数据形式:
通过键盘输入数据
输入值的范围:
树中元素的值为float型,范围为至+38;树的名称为char类型数据,可以输入字母,数字和符号,但是长度必须在20位以内;对菜单进行操作时,输入数据长度必须在200以内,且有效的输入数据为0至7,其中0为退出程序,1至7为对应菜单的操作选项。
输出数据形式:
输出到显示器。
程序功能
创建平衡二叉树存储结构,通过平衡因子,使二叉排序树达到平衡,提供平衡二叉树的创建、查找和删除,树中元素的查找、插入和删除等基本功能,可以实现创建多棵平衡二叉树,并且能够进行两棵树的合并。
通过平衡二叉树,能够使树时刻保持平衡,从而提高在树中遍历数据的速度,具有重要意义。
测试数据
1
建二叉平衡树"< cout<<"2.在树中查找元素"< cout<<"3.在树中插入元素"< cout<<"4.在树中删除元素"< cout<<"5.输出二叉平衡树结构示意图"< cout<<"6.合并两个二叉平衡树"< cout<<"7.删除二叉平衡树"< cout<<"请输入操作序号(输入0退出程序): "; (i,10*NAME_LENGTH,'\n'); if(strlen(i)! =1){continue;} else{ a=i[0]; if(a=='0'){ break; } } switch(a){ case'1': { system("cls"); cout<<"请输入需要创建的平衡树个数: "; intj,k; cin>>k; for(j=0;j cout<<"请输入第"< "; charname[NAME_LENGTH]; cin>>name; cout<<"请输入元素个数: "< intm,n; cin>>n; cout<<"请依次输入元素: "< Typee; AVLt=NULL; for(m=0;m cin>>; inttaller=0;< } else{cout<<"该树中不存在这个数! "< system("pause"); system("cls"); break; } case'3': { system("cls"); cout<<"请输入你想要访问的树名: "< charname[NAME_LENGTH]; cin>>name; Links; if(! SearchL(l,name,s)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } cout<<"请输入插入元素个数"< intm,n; cin>>n; cout<<"请依次输入插入元素"< Typee; for(m=0;m cin>>; inttaller=0;//增高标识,1为增高,0为不增高 InsertTree(s->t,e,taller); } cout<<"插入成功! "< system("pause"); system("cls"); break; } case'4': { system("cls"); cout<<"请输入你想要访问的树名: "< charname[NAME_LENGTH]; cin>>name; Links; if(! SearchL(l,name,s)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } cout<<"请输入删除元素个数"< intm,n; cin>>n; cout<<"请依次输入需要删除的元素"< Typee; for(m=0;m cin>>; intshorter=0;//降低表示,1为降低,0为不降低 DeleteTree(s->t,e,shorter); } cout<<"删除成功! "< system("pause"); system("cls"); break; } case'5': { system("cls"); cout<<"请输入你想要访问的树名: "< charname[NAME_LENGTH]; cin>>name; Links; if(! SearchL(l,name,s)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } if(s->t! =NULL){ cout< "< PrintTreeStructure(s->t); cout< } system("pause"); system("cls"); break; } case'6': { system("cls"); cout<<"请分别输入你想要合并的两个树的名字(会将后者合并到前者): "< charname1[NAME_LENGTH]; cin>>name1; Links1; if(! SearchL(l,name1,s1)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } charname2[NAME_LENGTH]; cin>>name2; Links2; if(! SearchL(l,name2,s2)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } else{ MergeTree(s1->t,s2->t);//将t2合并到t1上 DeleteL(s2);//删除链表结点l2 cout<<"合并树成功! "< system("pause"); system("cls"); break; } } case'7': { system("cls"); cout<<"请输入你想要删除的树的名字: "< charname[NAME_LENGTH]; cin>>name; Links; if(! SearchL(l,name,s)){ cout<<"未找到该名字的平衡树! "< system("pause"); system("cls"); break; } else{ DestroyTree(s->t); DeleteL(s); cout<<"删除树成功! "< system("pause"); system("cls"); break; } } } } } /**/ #include"" voidLeftBalance(AVL&t){//左部平衡化处理 AVLl,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){ caseLH: t->bf=RH; l->bf=EH; break; caseEH: t->bf=l->bf=EH; break; caseRH: t->bf=EH; l->bf=LH; break; } lr->bf=EH; L_Rotate(t->lchild); R_Rotate(t); } } voidRightBalance(AVL&t){//右部平衡化处理 AVLr,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){ caseLH: t->bf=EH; r->bf=RH; break; caseEH: t->bf=r->bf=EH; break; caseRH: t->bf=LH; r->bf=EH; break; } rl->bf=EH; R_Rotate(t->rchild); L_Rotate(t); } } /**/ #include"" intInsertTree(AVL&t,Typee,int&taller){//二叉平衡树的结点插入 if(! t){ t=(AVL)malloc(sizeof(AVLTree)); t->=; t->lchild=t->rchild=NULL; t->bf=EH; taller=1; } else{ if==t->{//找到重复元素时,不插入,返回0 taller=0; return0; } if if(! InsertTree(t->lchild,e,taller))return0;//找到重复元素,依次返回0,结束 if(taller){//插入左子树,且左子树变高 switch(t->bf){ case,需要做左平衡处理 LeftBalance(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))return0; if(taller){//插入右子树,且右子树长高 switch(t->bf){ case,现在左右子树等高 t->bf=EH; taller=0; break; case,现在右子树变高 t->bf=RH; taller=1; break; case,现在需做右平衡处理 RightBalance(t); taller=0; break; }//switch }//if }//else }//else return1; } /**/ #include"" intDeleteTree(AVL&t,Typee,int&shorter){//平衡二叉树的结点删除 if(t==NULL){//不存在该元素 return0;//删除失败 } elseif==t->{//找到元素结点 AVLq=NULL; if(t->lchild==NULL){//左子树为空 q=t; t=t->rchild; deleteq; shorter=1; } elseif(t->rchild==NULL){//右子树为空 q=t; t=t->lchild; deleteq; shorter=1; } else{//左右子树都存在 q=t->lchild; while(q->rchild){//找到要删除结点t的左孩子的最右孩子q q=q->rchild; } t->=q->;//把q的值给t DeleteTree(t->lchild,q->data,shorter);//在左子树中递归删除前驱结点。 即查找q的值 if(shorter){ switch(t->bf){ caseLH: t->bf=EH; shorter=1; break; caseEH: t->bf=RH; shorter=0; break; caseRH: if(t->rchild->bf==EH) shorter=0; else shorter=1; RightBalance(t);//右平衡处理 break; } } } } elseif if(! DeleteTree(t->lchild,e,shorter)){ return0; } if(shorter){ switch(t->bf){ caseLH: t->bf=EH; shorter=1; break; caseEH: t->bf=RH; shorter=0; break; caseRH: if(t->rchild->bf==EH) shorter=0; else shorter=1; RightBalance(t);//右平衡处理 break; } } } else{//右子树中继续查找 if(! DeleteTree(t->rchild,e,shorter)){ return0; } if(shorter){ switch(t->bf){ caseLH: if(t->lchild->bf==EH) shorter=0; else shorter=1; LeftBalance(t);//左平衡处理 break; caseEH: t->bf=LH; shorter=0; break; caseRH: t->bf=EH; shorter=1; break; } } } return1; } /**/ #include"" intDestroyTree(AVL&t){//递归销毁二叉平衡树 if(t==NULL){ return0; } DestroyTree(t->lchild); DestroyTree(t->rchild); free(t); return1; } /**/ #include"" intInitL(Link&l){//创建含一个空头结点的双向链表 if(! (l=(Link)malloc(sizeof(LNode))))return0; l->prior=l->next=NULL; l->t=NULL; return1; } intInsertL(Link&l,AVL&t,char*name){//在双向链表中插入元素 Linkp; p=(Link)malloc(sizeof(LNode)); p->t=t; strcpy(p->tree_name,name);//将平衡树的树名保存 p->next=l->next; if(l->next! =NULL)l->next->prior=p; l->next=p; p->prior=l; return1; } constintSearchL(Linkl,char*name,Link&s){//在链表中查询树名,成功则获取该链表结点的地址,返回true l=l->next; while(l! =NULL){ if(strcmp(l->tree_name,name)==0){ s=l; return1; } l=l->next; } return0; } intDeleteL(Link&l){//在链表中删除l结点 if(l->next==NULL){ l->prior->next=NULL; free(l); } else{ l->prior->next=l->next; l->next->prior=l->prior; free(l); } return1; } /**/ #include"" intMergeTree(AVL&t1,AVL&t2){//将树t2合并到t1上 while(t2! =NULL){ inttaller,shorter; InsertTree(t1,t2->data,taller); DeleteTree(t2,t2->data,shorter); } return1; } /**/ #include"" constintPrintTreeStructure(AVLt){//利用层次遍历,输出树的形状 if(! t){return0;} inti=0,level=0,j,num; LinkQq; InitQ(q); while (1){ i++; num=0; j=1; while(j<=i){ num++;//num为记层标志,记录当前T所在层数 j=2*j; } if(t! =NULL){ cout< EnQ(q,t->lchild); EnQ(q,t->rchild); if(j==i+1){ cout< } if(t->lchild==NULL&&t->rchild==NULL){//T为空时进行判断,当平衡树中出现层数不同的空结点时,终止输出 if(! level){//首次出现两个孩子都空的结点,将其孩子的层数赋给level level=num+1; } } } else{ EnQ(q,NULL);//若该点为空,则它的孩子也为空,入队列 EnQ(q,NULL); if(level&&level+2==num){ return1; } else{cout<<"*";}//用*代表空 if(j==i+1){ cout< } } DeQ(q,t); }//while } /**/ #include"" intInitQ(LinkQ&q){//创建空队列 ==(QP)malloc(sizeof(QNode)); if(! return0; >next=NULL; return1; } intEnQ(LinkQ&q,AVLe){//入队列 QPp; p=(QP)malloc(sizeof(QNode)); if(! p)return0; p->tree=e; p->next=NULL; >next=p; =p; return1; } intDeQ(LinkQ&q,AVL&e){//出队列 if==return0; QPp; p=>next; e=p->tree; >next=p->next; if==p)=; free(p); return1; } /**/ #include"" voidR_Rotate(AVL&t){//以T为根节点的二叉排序树进行右旋转 AVLl; l=t->lchild; t->lchild=l->rchild; l->rchild=t; t=l;//p指向新的根节点 } voidL_Rotate(AVL&t){//以T为根节点的二叉排序树进行左旋转 AVLr; r=t->rchild; t->rchild=r->lchild; r->lchild=t; t=r; } /**/ #include"" constintSearchTree(AVLt,Typekey,AVL&p){//搜索树中是否包含该元素 while(t){ if==t->{p=t;return1;} elseif p=t; t=t->lchild; } else{ p=t; t=t->rchild; } } return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验四 平衡二叉树演示 实验 平衡 二叉 演示