广工数据结构实验报告平衡二叉树
更新时间:2023-10-06 10:45:01 阅读量: 综合文库 文档下载
数据结构实验报告
题目:平衡二叉树
学 院 专 业 年级班别 学 号 学生姓名 指导教师
2015年7月1日
1.题目:采用字符类型为整型类型和链式存储结构,实现抽象数据类型BTree。 ADT BTree{
数据对象:D={ai | ai∈ElemSet, i=1,2,...,n, n≥0 } 数据关系:R1={ |ai-1, ai∈D, i=2,...,n } 基本操作: Adj_balance(T)
操作结果:创建平衡二叉树。 InsertAVL(T,search,taller)
初始条件:二叉树T已存在。 操作结果:增加新结点。 SetAVL(T,search,taller)
初始条件:二叉树T已存在。
操作结果:在平衡二叉树上增加新结点并调平衡。 DeleteAVL(T,search,shorter)
初始条件:二叉树T已存在。 操作结果:删除结点。 } ADT BTree 2.存储结构定义
公用头文件DS0.h: #include
typedef struct BTNode {
int data;
int bf; //平衡因子
struct BTNode *lchild,*rchild;//左、右孩子 }BTNode,*BTree; /*需要的函数声明*/
void Right_Balance(BTree &p); void Left_Balance(BTree &p);
void Left_Root_Balance(BTree &T); void Right_Root_Balance(BTree &T);
bool InsertAVL(BTree &T,int i,bool &taller); void PrintBT(BTree T);
void Left_Root_Balance_det(BTree &p,int &shorter); void Right_Root_Balance_det(BTree &p,int &shorter); void Delete(BTree q,BTree &r,int &shorter); int DeleteAVL(BTree &p,int x,int &shorter); void Adj_balance(BTree &T);
bool SetAVL(BTree &T,int i,bool &taller);
bool Insert_Balance_AVL(BTree &T,int i,bool &taller); int menu( ); 3. 算法设计
/*对以*p为根的二叉排序树作右旋处理*/ void Right_Balance(BTree &p) {
BTree lc;
lc =p->lchild; //lc指向的*p左子树根结点 p->lchild = lc->rchild; //rc的右子树挂接为*p的左子树 lc->rchild = p;
p = lc; //p指向新的结点 }
/*对以*p为根的二叉排序树作左旋处理*/ void Left_Balance(BTree &p) {
BTree rc;
rc = p->rchild; //指向的*p右子树根结点 p->rchild = rc->lchild; //rc左子树挂接到*p的右子树 rc->lchild = p;
p = rc; //p指向新的结点 }
/*对以指针T所指结点为根的二叉树作左平衡旋转处理*/ void Left_Root_Balance(BTree &T) {
BTree lc,rd;
lc = T->lchild; //指向*T的左子树根结点
switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理 {
case 1: //新结点插入在*T的左孩子的左子树上,要作单右旋处理
T->bf = lc->bf = 0; Right_Balance(T); break;
case -1: //新结点插入在*T的左孩子的右子树上,要作双旋处理
rd = lc->rchild; //rd指向*T的左孩子的右子树根 switch(rd->bf) //修改*T及其左孩子的平衡因子 {
case 1:
T->bf = -1; lc->bf = 0; break; case 0:
T->bf = lc->bf = 0; break; case -1:
T->bf = 0;
lc->bf = 1; break; }
rd->bf = 0;
Left_Balance(T->lchild); //对*T的左子树作左旋平衡处理 Right_Balance(T); //对*T作右旋平衡处理 } }
/*对以指针T所指结点为根的二叉树作右平衡旋转处理*/ void Right_Root_Balance(BTree &T) {
BTree rc,ld;
rc = T->rchild; //指向*T的左子树根结点
switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理 {
case -1: //新结点插入在*T的右孩子的右子树上,要作单左旋处理
T->bf = rc->bf =0;
Left_Balance(T); break;
case 1: //新结点插入在*T的右孩子的左子树上,要作双旋处理
ld = rc->lchild; //ld指向*T的右孩子的左子树根 switch(ld->bf) //修改*T及其右孩子的平衡因子 {
case 1:
T->bf = 0; rc->bf = -1; break; case 0:
T->bf = rc->bf =0; break; case -1:
T->bf = 1; rc->bf = 0; break; }
ld->bf = 0;
Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理 Left_Balance(T); //对*T作左旋平衡处理 } }
/*插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0*/
bool InsertAVL(BTree &T,int i,bool &taller)
{
if(!T)//插入新结点,树“长高”,置taller为true {
T = (BTree)malloc(sizeof(BTNode)); T->data = i;
T->lchild = T->rchild =NULL; T->bf = 0; taller = true; } else {
if(i==T->data) //树中已存在和有相同关键字的结点 {
taller = 0;
printf(\已存在相同关键字的结点\\n\ return 0; }
if(i
if(!InsertAVL(T->lchild,i,taller)) return 0; }
else //应继续在*T的右子树中进行搜索
{
if(!InsertAVL(T->rchild,i,taller)) return 0; } }
return 1; }
/*输出二叉树*/
void PrintBT(BTree T) {
if(T) {
printf(\ if(T->lchild||T->rchild) {
printf(\
PrintBT(T->lchild); printf(\
PrintBT(T->rchild); printf(\
} } }
/*删除结点时左平衡旋转处理*/
void Left_Root_Balance_det(BTree &p,int &shorter) {
BTree p1,p2;
if(p->bf==1) //p结点的左子树高,删除结点后p的bf减,树变矮 {
p->bf=0; shorter=1; }
else if(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; }
else if(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; }
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 Right_Root_Balance_det(BTree &p,int &shorter) {
BTree 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) {
Right_Balance(p); p1->bf=-1; p->bf=1; shorter=0; }
else if(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; }
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(BTree q,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); } }
/*二叉树的删除操作*/
int DeleteAVL(BTree &p,int x,int &shorter) {
int k; BTree q;
if(p==NULL) {
printf(\不存在要删除的关键字!!\\n\ return 0; }
else if(x
k=DeleteAVL(p->lchild,x,shorter); if(shorter==1)
Left_Root_Balance_det(p,shorter); return k; }
else if(x>p->data)//在p的右子树中进行删除 {
k=DeleteAVL(p->rchild,x,shorter); if(shorter==1)
Right_Root_Balance_det(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)
Left_Root_Balance_det(p,shorter); p=q; }
return 1; } }
/*调平二叉树具体方法*/
bool SetAVL(BTree &T,int i,bool &taller) {
if(!T)//插入新结点,树“长高”,置taller为true {
T = (BTree)malloc(sizeof(BTNode)); T->data = i;
T->lchild = T->rchild =NULL; T->bf = 0; taller = true; } else {
if(i==T->data) //树中已存在和有相同关键字的结点 {
taller = false;
printf(\已存在相同关键字的结点\\n\ return 0; }
if(i
if(!SetAVL(T->lchild,i,taller)) return 0;
if(taller) //已插入到*T的左子树中且左子树“长高”
switch(T->bf) //检查*T的平衡度 {
case 1: //原本左子树比右子树高,需要作左平衡处理
Left_Root_Balance(T); taller = false; break;
case 0: //原本左子树、右子等高,现因左子树增高而使树增高
T->bf = 1; taller = true; break;
case -1: //原本右子树比左子树高,现左、右子树等高
T->bf = 0; taller = false; break; } }
else //应继续在*T的右子树中进行搜索
{
if(!SetAVL(T->rchild,i,taller)) return 0;
if(taller) //已插入到*T的右子树中且右子树“长高”
switch(T->bf) //检查*T的平衡度 {
case 1: //原本左子树比右子树高,现左、右子树等高
T->bf = 0; taller = false; break;
case 0: //原本左子树、右子等高,现因右子树增高而使树增高
T->bf = -1; taller = true; break;
case -1: //原本右子树比左子树高,需要作右平衡处理
Right_Root_Balance(T); taller = false; break; } }
return 1; } }
/*二叉树调平操作*/
void Adj_balance(BTree &T) {
int i;
bool taller=false; T = NULL;
printf(\请输入关键字(以-1结束建立平衡二叉树):\ scanf(\ getchar(); while(i != -1) {
SetAVL(T,i,taller);
printf(\请输入关键字(以-1结束建立平衡二叉树):\ scanf(\ getchar(); taller=false; }
printf(\平衡二叉树创建结束.\\n\ if(T)
PrintBT(T); else
printf(\这是一棵空树.\\n\}
/*菜单函数*/ int menu( ) {
int m;
printf(\年7月1日......................\\n\\n\ printf(\ 平衡二叉树\\n\
printf(\ ________________________________\\n\\n\ printf(\ 1 创建平衡二叉树\\n\
printf(\ 2 在平衡二叉树上增加新结点并调衡\\n\ printf(\ 3 在平衡二叉树上删除一个结点并调衡\\n\ printf(\ 0 退出\\n\
printf(\ ________________________________\\n\\n\ printf(\ 请输入所选功能0-3\\n\ scanf(\ return m; }
4.测试 /*主函数*/ void main() {
int input,search; bool taller=0; int shorter=0; BTree T;
T=(BTree)malloc(sizeof(BTNode)); T=NULL; while(1) {
printf(\请选择需要的二叉树操作\\n\ input=menu( ); switch(input) {
case 1:
Adj_balance(T); break; case 2:
printf(\请输入你要增加的关键字\ scanf(\ getchar();
SetAVL(T,search,taller); PrintBT(T); break; case 3:
printf(\请输入你要删除的关键字\ scanf(\ getchar();
DeleteAVL(T,search,shorter); PrintBT(T); break; case 0: break; default:
printf(\输入错误,请重新选择。\ break; }
if(input == 0) break;
printf(\按任意键继续.\ getchar(); } }
测试截图:
1.界面:
2.创建平衡二叉树:
3.增加节点并调衡:
4.删除节点并调衡:
5. 思考与小结
在平衡二叉树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。
scanf(\ return m; }
/*主函数*/ void main() {
int input,search; bool taller=0; int shorter=0; BTree T;
T=(BTree)malloc(sizeof(BTNode)); T=NULL; while(1) {
printf(\请选择需要的二叉树操作\\n\ input=menu( ); switch(input) {
case 1:
Adj_balance(T); break; case 2:
printf(\请输入你要增加的关键字\ scanf(\ getchar();
SetAVL(T,search,taller); PrintBT(T); break; case 3:
printf(\请输入你要删除的关键字\ scanf(\ getchar();
DeleteAVL(T,search,shorter); PrintBT(T); break; case 0: break; default:
printf(\输入错误,请重新选择。\ break; }
if(input == 0) break;
printf(\按任意键继续.\ getchar(); } }
正在阅读:
广工数据结构实验报告平衡二叉树10-06
5营销环境分析01-15
—转换器报告 - 图文09-25
新视野大学英语网上测试10-22
高空作业安全免责协议08-22
三年级上册品德一课一练第一单元第一课天生我材必有用 浙教版12-14
我能小学作文06-15
粤教版小学四年级品德与社会期末复习总结03-18
中药鉴定学 复习资料01-29
- 冀教版版五年级科学下册复习资料
- 微生物学复习提纲
- 2013—2014学年小学第二学期教研组工作总结
- 国有土地转让委托服务合同协议范本模板
- 我的固废说明书
- 企业管理诊断报告格式
- 东鼎雅苑施工组织设计
- 谈谈如何做好基层党支部书记工作
- 浮梁县环保局市级文明单位创建工作汇报
- 管理学基础知识
- 大学物理实验报告23 - PN结温度传感器特性1
- 计算机网络实践
- 酒桌上这四种情况下要坐牢,千万别不当回事……
- 国家康居示范工程建设技术要点
- 中国贴布行业市场调查研究报告(目录) - 图文
- 新课标下如何在高中物理教学中培养学生的创新能力初探
- 营养师冬季养生食谱每日一练(7月4日)
- 关注江西2017年第3期药品质量公告
- 建设海绵城市专题习题汇总
- 10万吨年环保净水剂建设项目报告书(2).pdf - 图文
- 数据结构
- 平衡
- 实验
- 报告
- 保育员实操模拟试卷3
- 30000亩日本优质、薄皮“清香”中晚实良种核桃种植示范基地项目可研报告 定稿 - 图文
- 关于开展全省水利工程施工新资质企业《安全生产考核合格证》取证考核工作的通知
- 《冷热不均引起大气运动》同步练习
- 8册语文课内阅读练习题
- (上传)2014华南师范大学网络教育学院税法100分作业
- 社交礼仪培训心得体会
- 九年级英语环保渗透教案
- EDIUS教程二-开始认识EDIUS - 图文
- 论我国政府信息公开立法发展问题
- 纳税评估工作中存在的廉政隐患与对策
- 铁路局小型养路机械操作方案 - 图文
- ANSYS有限元分析实验报告
- 现代教育技术题库
- HS公司海船船员人力资源流失问题研究4-15(1)
- 市场调研与销售预测
- 武汉理工大学机械工程及自动化专业卓越工程师培养方案 - 图文
- 管理定量分析习题
- 小升初数学必备专题之质数
- 贵州啤酒业市场现状分析