一、题目描述

利用平衡二叉树实现一个动态查找表,实现动态查找表的三种基本功能:查找、插入和删除。

二、需求分析

1.建立平衡二叉树并进行创建、查找、插入、删除等功能。

2.设计一个实现平衡二叉树的程序,可进行创建、查找、插入、删除等操作,实现动态的输入数据,实时的输出该树结构。

3.测试数据:自选数据

三、概要设计

1.抽象数据类型定义:

typedef struct BSTNode {

int data;

int bf;                         //节点的平衡因子

structBSTNode *lchild,*rchild;    //左右孩子指针

}BSTNode,*BSTree;

voidCreatBST(BSTree &T);        //创建平衡二叉树

voidR_Rotate(BSTree &p);         //对以*p为根的二叉排序树作左旋处理

voidL_Rotate(BSTree &p);         //对以*p为根的二叉排序树作左旋处理

voidLeftBalance(BSTree &T);      //对以指针T所指结点为根的二叉树作左平衡旋转处理

voidRightBalance(BSTree &T);    //对以指针T所指结点为根的二叉树作右平衡旋转处理

boolInsertAVL(BSTree &T,int e,bool &taller);          //插入结点e

boolSearchBST(BSTree &T,int key);                 //查找元素key是否在树T中

void LeftBalance_div(BSTree &p,int&shorter);        //删除结点时左平衡旋转处理

void RightBalance_div(BSTree &p,int&shorter);       //删除结点时右平衡旋转处理

void Delete(BSTreeq,BSTree  &r,int &shorter);       //删除结点

int DeleteAVL(BSTree &p,int x,int&shorter);          //平衡二叉树的删除操作

void PrintBST(BSTree T,int m);                     //按树状打印输出二叉树的元素

2.主程序的流程

请输入操作的选项编号(1-5)

1---创建平衡二叉树

2---查找

3---插入

4---删除

5---结束

3.各模块之间的层次调用

四、详细设计

1.以平衡二叉树的插入和平衡化为例:

bool InsertAVL(BSTree &T,int e,bool&taller)

{

//若存在平衡的二叉排序树T中不存在和e有相同关键字的节点,则插入一个数据元素为e

//的新结点,并返回1,否者返回0。若因插入而使二叉排序树失去平衡,则作平衡旋转理,

//布尔变量taller反映T长高与否。

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

{

T = (BSTree)malloc(sizeof(BSTNode));

T->data = e;

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

T->bf = EH; taller = true;

}

else

{

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

{ taller = false;printf("已存在相同关键字的结点\n"); return 0; }//则不再插入

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

{

if(!InsertAVL(T->lchild,e,taller)) return 0;//未插入

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

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

{

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

LeftBalance(T); taller =false; break;

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

T->bf = LH; taller =true; break;

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

T->bf = EH; taller =false; break;

}//switch(T->bf)

}//if

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

{

if(!InsertAVL(T->rchild,e,taller))return 0;//未插入

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

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

{

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

T->bf = EH; taller =false; break;

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

T->bf = RH; taller =true; break;

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

RightBalance(T); taller= false; break;

}//switch(T->bf)

}//else

}//else

return 1;

}//InsertAVL

2.说明:执行完输入函数后,会在键盘缓冲区中保存回车键,后面再对字符型量

赋值时,会将缓冲区当成数据存入变量中,所以要在某些输入语句后面加getchar

函数。

五、调试分析

1. 遇到的问题

(1)对平衡二叉树的删除的算法设计程序存在很大问题。删除节点后需要对新的排序树平衡化,改变节点的信息,使之形成一棵新的平衡二叉树。

(2)主函数中的实参和子函数中的实参相等,造成调用该子函数时,虽然没有错误,但其功能不能正确的实现。改变该变量后程序成功实现各种功能。

(3)一些逻辑逻辑运算符书写不正确,造成实现的功能不正确或程序死循环。

六、用户使用说明

1.了解程序清单上给出的功能,并根据提示依次进行操作。

2.创建二叉树,输入的数据元素为整数,当输入-123时,停止创建。并显示平衡二叉树的中序凹入树形图。

3.查找(输入你要查找的元素)。

4.插入(输入要插入的数据元素,并输出)

5.删除(删除指定的元素,并输出)

6.结束

说明:其中每一个功能实现后都会提示是否继续:选择y继续,否则,终止。

 

七、总结

经过这次课程设计实验,我体会到只有保持耐心,坚持到底才有可能做好事情。这次课程设计加强了我动手解决问题的能力,巩固和加深了对数据结构的理解,提高了综合运用课程知识的能力,培养了独立思考、深入研究、分析问题和解决问题的能力。

同时,我也明白了将理论知识与实际相结合的重要性,只有理论知识远远不够,因为在实际设计中还是会遇到不少问题,这次实验使我发现了自己很多知识漏洞,这对我今后的学习来说是一次非常宝贵的体验。

收获:

1)对平衡二叉树的构造、插入和删除的算法思想有了更清楚的认识,能够对平衡二叉树进行创建、调平、插入、删除等操作,实现动态的输入数据,实时的输出该树结构.

2)对多个程序的调用

八、附录

源代码:

#include<stdio.h>
#include<stdlib.h>#define LH +1
#define EH 0
#define RH -1
#define NULL 0typedef struct BSTNode {int data;int bf;struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;void CreatBST(BSTree &T);
void R_Rotate (BSTree &p);
void L_Rotate(BSTree &p);
void LeftBalance(BSTree &T);
void RightBalance(BSTree &T);
bool InsertAVL(BSTree &T,int e,bool &taller);
bool SearchBST(BSTree &T,int key);
void LeftBalance_div(BSTree &p,int &shorter);
void RightBalance_div(BSTree &p,int &shorter);
void Delete(BSTree q,BSTree  &r,int &shorter);
int DeleteAVL(BSTree &p,int x,int &shorter);
void PrintBST(BSTree T,int depth);void main()
{BSTree T;int sear,cmd,depth;char ch;int shorter=0;bool taller=false;T=(BSTree)malloc(sizeof(BSTNode));T=NULL;printf("****************平衡二叉树的操作菜单****************\n");printf("                    1--创建\n");printf("                    2--查找\n");printf("                    3--插入\n");printf("                    4--删除\n");printf("                    5--退出\n");printf("****************************************************\n");do{printf("\n请选择操作的编号:");scanf("%d",&cmd);getchar();switch(cmd){case 1:CreatBST(T);break;case 2:printf("请输入您要查找的关键字:");scanf("%d",&sear);getchar();if(SearchBST(T,sear)) printf("关键字%d存在,查找成功!\n",sear);else printf("查找失败!\n");break;case 3:printf("请输入您要插入的关键字:");scanf("%d",&sear);getchar;InsertAVL(T,sear,taller);depth=0;PrintBST(T,depth);break;case 4:depth=0;printf("请输入你要删除的关键字: ");scanf("%d",&sear); getchar();DeleteAVL(T,sear,shorter);PrintBST(T,depth); break;case 5:printf("结束!\n");break;default:printf("输入错误!\n");}if(cmd==5)break;printf("\n继续吗? y/n: ");scanf("%s",&ch);getchar();printf("\n");}while(ch=='y');printf("\n");
}void CreatBST(BSTree &T)
{int depth;int e;bool taller=false;T = NULL;printf("\n请输入关键字(以-123结束建立平衡二叉树):");scanf("%d",&e);getchar();while(e != -123){InsertAVL(T,e,taller);printf("\n请输入关键字(以-123结束建立平衡二叉树):");scanf("%d",&e);getchar();taller=false;}depth=0;printf("\n****************************************************\n");printf("                 您创建的二叉树为\n");if(T)PrintBST(T,depth);elseprintf("这是一棵空树!\n");
}void R_Rotate (BSTree &p)    //对以*p为根的二叉排序树作右旋处理
{BSTree lc;lc=p->lchild;p->lchild=lc->rchild;lc->rchild=p;p=lc;
}void L_Rotate(BSTree &p)   //对以*p为根的二叉排序树作左旋处理
{BSTree rc;rc=p->rchild;p->rchild=rc->lchild;rc->lchild=p;p=rc;
}void LeftBalance(BSTree &T)    //对以指针T所指结点为根的二叉树作左平衡旋转处理
{BSTree lc,rd;lc=T->lchild;switch(lc->bf){case LH:T->bf=lc->bf=EH;R_Rotate(T);break;case RH:rd=lc->rchild;switch(rd->bf){case LH:T->bf=RH;lc->bf=EH;break;case EH:T->bf=lc->bf=EH;break;case RH:T->bf=EH;lc->bf=LH;break;}rd->bf=EH;L_Rotate(T->lchild);R_Rotate(T);}
}void RightBalance(BSTree &T)     //对以指针T所指结点为根的二叉树作右平衡旋转处理
{BSTree rc,ld;rc=T->rchild;switch(rc->bf){case RH:T->bf=rc->bf=EH;L_Rotate(T);break;case LH:ld=rc->lchild;switch(ld->bf){case RH:T->bf=LH;rc->bf=EH;break;case EH:T->bf=rc->bf=EH;break;case LH:T->bf=EH;rc->bf=RH;break;}ld->bf=EH;R_Rotate(T->rchild);L_Rotate(T);}
}bool InsertAVL(BSTree &T,int e,bool &taller)  //插入结点e
{if(!T){T=(BSTree)malloc(sizeof(BSTNode));T->data=e;T->lchild=T->rchild=NULL;T->bf=EH;taller=true;}else{if(e==T->data){taller=false;printf("已存在相同关键字的结点!\n");return 0;}if(e<T->data){if(!InsertAVL(T->lchild,e,taller))return 0;if(taller)switch(T->bf){case LH:LeftBalance(T);taller=false;break;case EH:T->bf=LH;taller=true;break;case RH:T->bf=EH;taller=false;break;}}else{if(!InsertAVL(T->rchild,e,taller))return 0;if(taller)switch(T->bf){case LH:T->bf=EH;taller=false;break;case EH:T->bf=RH;taller=true;break;case RH:RightBalance(T);taller=false;break;}}}
}bool SearchBST(BSTree &T,int key)   //查找元素key是否在树T中
{if(!T)return false;else if(key==T->data)return true;else if(key<T->data)return SearchBST(T->lchild,key);elsereturn SearchBST(T->rchild,key);
}void LeftBalance_div(BSTree &p,int &shorter)     //删除结点时左平衡旋转处理
{BSTree  p1,p2;if(p->bf==1) { p->bf=0; shorter=1; }else if(p->bf==0){ p->bf=-1; shorter=0; }else  {p1=p->rchild;if(p1->bf==0){L_Rotate(p);p1->bf=1; p->bf=-1; shorter=0;}else if(p1->bf==-1){L_Rotate(p);p1->bf=p->bf=0; shorter=1;}else {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; }else if(p2->bf==-1){ p->bf=1;p1->bf=0; }else { p->bf=0;p1->bf=-1; }p2->bf=0; p=p2; shorter=1;}}}void RightBalance_div(BSTree &p,int &shorter)    //删除结点时右平衡旋转处理
{BSTree  p1,p2;if(p->bf==-1){ p->bf=0; shorter=1; }else if(p->bf==0){ p->bf=1; shorter=0; }else{ p1=p->lchild;if(p1->bf==0){R_Rotate(p);p1->bf=-1; p->bf=1; shorter=0;}else if(p1->bf==1){R_Rotate(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; }else if(p2->bf==1){ p->bf=-1; p1->bf=0; }else { p->bf=0; p1->bf=1; }p2->bf=0; p=p2; shorter=1;}}
}void Delete(BSTree q,BSTree  &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) RightBalance_div(r,shorter);}
}int DeleteAVL(BSTree &p,int x,int &shorter)      //平衡二叉树的删除操作
{int k;BSTree q;if(p==NULL)  { printf("不存在要删除的关键字!\n"); return 0;}else if(x<p->data){ k=DeleteAVL(p->lchild,x,shorter);if(shorter==1)LeftBalance_div(p,shorter);return k;}else if(x>p->data){k=DeleteAVL(p->rchild,x,shorter);if(shorter==1)RightBalance_div(p,shorter);return k;}else{q=p;if(p->rchild==NULL) { p=p->lchild; free(q); shorter=1; }else if(p->lchild==NULL){ p=p->rchild; free(q); shorter=1; }else{Delete(q,q->lchild,shorter);if(shorter==1)LeftBalance_div(p,shorter);p=q; }return 1;}
}void PrintBST(BSTree T,int depth)
{int i;if(T->rchild)PrintBST(T->rchild,depth+1);for(i=1;i<=depth;i++)printf("     ");printf("%d\n",T->data);if(T->lchild)PrintBST(T->lchild,depth+1);
}

数据结构实验--平衡二叉树操作的演示相关推荐

  1. 平衡二叉树操作的演示

    平衡二叉树操作的演示 // @author: Folivora Li // @copyright: Folivora Li/*23.[3]平衡二叉树操作的演示(选做) (查找) [问题描述] 利用平衡 ...

  2. 数据结构实验:图遍历的演示

    数据结构实验四:图遍历的演示 实验题目描述 1.基本要求 2.参考 实验过程 1.开发环境描述 2.题目分析及解题思路 3.实验代码 4.文件 联系我 实验题目描述 1.基本要求 ① 很多涉及图上操作 ...

  3. 3374——数据结构实验之查找二:平衡二叉树

    数据结构实验之查找二:平衡二叉树 ( LL RR LR RL) Problem Description 根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根. Input 输入一组测试数据 ...

  4. 广州大学学生实验报告,数据结构实验,二叉树的操作与实现

    广州大学学生实验报告 开课学院及实验室: 计算机科学与工程实验室 418              2022年10月3日 学院 计算机科学与网络工程 年级.专业.班 计科 姓名 Great Macro ...

  5. 大学计算机打开文件过程演示实验记录表,操作系统进程与文件管理 实验报告表 作业 5.doc...

    精品文档 . (本文档包含: 实验5 实验报告 与 第5周作业题) 实验5 操作系统进程与文件管理 实验报告 学号 1404505147 姓名禤雨骅 班级: 临床医学14(1) 实验时间:2015 年 ...

  6. 数据结构实验六 图的操作实现

    数据结构实验六 图的操作实现 一.实验目的 1. 理解图的存储结构与基本操作: 2. 掌握图的创建过程 二.实验内容 1.根据下图,采用邻接矩阵的存储结构保存此图,并打印出邻接矩阵. 图的创建代码参考 ...

  7. 数据结构实验三 图的操作与实现

    系列文章: 数据结构实验一 线性表.堆栈和队列的操作与实现 数据结构实验二 二叉树的操作与实现 数据结构实验三 图的操作与实现 数据结构实验四 查找和排序算法实现 一.实验目的: 1.领会图的两种主要 ...

  8. SUTD OJ 数据结构实验之查找二:平衡二叉树

    数据结构实验之查找二:平衡二叉树 Time Limit: 400 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 根据给 ...

  9. 数据结构实验二 :二叉树的操作与实现

    数据结构实验一:线性表,堆栈和队列实现 数据结构实验二 :二叉树的操作与实现 数据结构实验三: 图的操作与实现 数据结构实验四 : 查找和排序算法实现 文章目录 一.实验目的: 二.使用仪器.器材 三 ...

最新文章

  1. linux setcap指令,Linux下setcap详解
  2. 微型计算机的发展通常以为技术指标,计算机组成原理期末复习题.doc
  3. Android Studio签名打包的两种方式
  4. BZOJ 3786: 星系探索 欧拉游览树
  5. 云联会企业认证_今日新鲜事:沉浸式交互购车新体验 2020首届中国春季云车展启幕...
  6. springboot 打印slf4_SpringBoot 整合 slf4j 日志打印
  7. (97)FPGA边沿检测(上升沿检测)
  8. sql语句优化的几种方法
  9. NLPIR/ICTCLAS 2015 分词系统使用
  10. linux7找回删除的文件,centos7 rm -rf 删除文件的找回
  11. 两晋南北朝·高洋(上)
  12. python抠图教程_简单几行Python代码实现8秒抠图的AI神器,根本无需PS(附教程)...
  13. 基于深度学习的人脸识别考勤系统设计
  14. 为何要重建索引 index
  15. 二手车价格预测数据探索
  16. java基础知识之一:命名规则(包名、类名、变量名、方法名)
  17. R包自带数据汇总(自带数据包:datasets)
  18. 旅游业如何使用数据分析?
  19. 智能调度与仿真技术在工厂物流中的应用
  20. Python实现音乐播放器

热门文章

  1. 服务器租赁是什么意思,服务器托管是什么意思
  2. 如何将网站提交到百度、Google等搜索引擎?
  3. python使用国内源安装包
  4. 微软出品·kubernetes学习路线
  5. 从三国演义谈创业的一点启示
  6. IDBDatabase的数据库操作
  7. 解决openEuler网络配置ens33网卡问题
  8. 阿里云备案服务码申请方法流程
  9. 告别福禄克DTX系列,欢迎dsx2-5000网线测试
  10. win7计算机脱机,Win7系统IE脱机状态怎么解除?