平衡二叉树(AVL)的查找、插入和删除

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

平衡二叉树(AVL)查找、插入和删除
小组成员:
陈静101070009
陈丹璐101070006
陈娇101070008
目录
平衡二叉树(AVL) (1)
查找、插入和删除 (1)
问题描述 (2)
设计说明 (3)
(一)ADT (3)
(二)算法思想 (5)
(三)数据结构 (12)
(四)程序结构与流程 (13)
运行平台及开发工具 (15)
I/O格式 (15)
算法复杂度分析 (18)
源代码 (18)
小结 (37)
问题描述
利用平衡二叉树实现一个动态查找表。

(1)实现动态查找表的三种基本功能:查找、插入和删除。

(2)初始时,平衡二叉树为空树,操作界面给出创建、查找、插入和删除和退出五种操作供选择。

每种操作均要提示输入关键字。

创建时,根据提示输入数据,以-1为输入数据的结束标志,若输入数据重复,则给出已存在相同关键字的提示,并不将其插入到二叉树中。

在查找时,如果查找的关键字不存在,则显示不存在查找的关键字,若存在则显示存在要查找的关键字。

插入时首先检验原二叉树中是否已存在相同第3 页共38 页- 3 -的关键字,若没有则进行插入并输出二叉树,若有则给出已有相同关键字的提醒。

删除时首先检验原二叉树中是否存在要删除的关键字,若有则进行删除后并输出二叉树,若没有则给出不存在要删除的关键字的提醒。

(3)平衡二叉树的显示采用中序遍历的方法输出,还可以根据输出数据是否有序验证对平衡二叉树的操作是否正确。

设计说明
(一)ADT
ADT BalancedBinaryTree{
数据对象D:D是具有相同特性的数据元素的集合。

各个数据元素均含有类型相同,可唯一标志的数据元素的关键字。

数据关系R:数据元素同属一个集合。

基本操作P:
void R_Rotate(BSTree &p);
初始条件:二叉树存在,且关键字插入到以*p为根的二叉树的左子树的左孩子上;
操作结果:对以*p为根的二叉排序树作右旋处理
void L_Rotate(BSTree &p);
初始条件:二叉树存在,且关键字插入到以*p为根的二叉树的右子树的右孩子上;
操作结果:对以*p为根的二叉排序树作左旋处理
void LeftBalance(BSTree &T);
初始条件:二叉树存在,且关键字插入到T所指节点为根的二叉树的左子树的右孩子上;操作结果:对以指针T所指结点为根的二叉树作左平衡旋转处理
void RightBalance(BSTree &T);
初始条件:二叉树存在,且关键字插入到T所指节点为根的二叉树的右子树的左孩子上;操作结果:对以指针T所指结点为根的二叉树作右平衡旋转处理
bool InsertAVL(BSTree &T,int e,bool &taller);
初始条件:T存在,且e与二叉树的原有关键字不同;
操作结果:插入结点e平且平衡化;
bool SearchBST(BSTree &T,int key);
初始条件:T存在且元素key与某关键字相同;
操作结果:查找元素key是否在树T中
void PrintBST(BSTree T);
初始条件:T存在
操作结果:按中序遍历输出二叉树的元素
void CreatBST(BSTree &T);
初始条件:T为空
操作结果:创建平衡二叉树,(注意:以输入-1为二叉树建立的结束)
void LeftBalance_div(BSTree &p,int &shorter);
初始条件:T存在
操作结果:删除结点时左平衡旋转处理
void RightBalance_div(BSTree &p,int &shorter);
初始条件:T存在
操作结果:删除结点时右平衡旋转处理
void Delete(BSTree q,BSTree &r,int &shorter);
初始条件:T存在且节点删除成功
操作结果:删除结点
int DeleteAVL(BSTree &p,int x,int &shorter);
初始条件:
操作结果:平衡二叉树的删除操作
} ADT BalancedBinaryTree
(二)算法思想
1、查找
在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。

如果树T为空,则查找不成功,返回空指针;当树T非空时,如果根指针T所指数据元素的关键字等于key,则查找成功,返回根指针T,否则在左子树中继续查找,若还未找到,则继续在右子树中进行查找,直到找到该数据元素或树T为空为止。

//查找元素key是否在树T中
bool SearchBST(BSTree &T,int key)
{
if(!T) return false;
else if(EQ(key,T->data)) return true;
else if(LT(key,T->data)) return SearchBST(T->lchild,key);
else return SearchBST(T->rchild,key);
}
2、插入
(一)若T为空树,则插入一个数据元素为e的新节点作为T的根节点,树长高,树的深度增加1。

(二)若待插入的数据元素e与T的根节点的关键字相同,则不进行插入。

(三)若待插入的数据元素e小于根节点的关键字,且在T的左子树上不存在与e相等的数据元素,那么将e插入到T的左子树上。

下面就插入到左子树之后,就不同的情况进行处理:
①若之前T的根节点的平衡因子为-1,将根节点的平衡因子变为0,T的深度不变;
②若之前T的根节点的平衡因子为0,就将根节点的平衡因子变为1,T的深度增加;
③若之前的T的根节点的平衡因子为1,那么当其左子树的根节点的平衡因子为1的时候,需要进行单向右旋处理,并且在右旋处理之后,将根节点和其右子树根节点的平衡因子改为0,树的深度不变;当其左子树的根节点的平衡因子为-1的时候,要进行先左后右的双向旋转平衡,并在旋转之后,修改根节点和其左右子树的根节点的平衡因子,树的深度不
(四)若待插入的数据元素e大于根节点的关键字,且在T的右子树上不存在与e相等的数据元素,那么将e插入到T的右子树上。

下面就插入到右子树之后,就不同的情况进行处理:
①若之前T的根节点的平衡因子为1,将根节点的平衡因子变为0,T的深度不变;
②若之前T的根节点的平衡因子为0,就将根节点的平衡因子变为1,T的深度增加;
③若之前的T的根节点的平衡因子为-1,那么当其右子树的根节点的平衡因子为-1的时候,需要进行单向左旋处理,并且在左旋处理之后,将根节点和其左子树根节点的平衡因子改为0,树的深度不变;当其右子树的根节点的平衡因子为1的时候,要进行先右后左的双向旋转平衡,并在旋转之后,修改根节点和其左右子树的根节点的平衡因子,树的深度不变。

//插入结点e,若T中不存在和e相同关键字的结点,则插入一个数据元素为e的新结点,并返回1,否则返回0
bool InsertAVL(BSTree &T,int e,bool &taller)
{
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;
}
}
}
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;
}
}
}
}
return 1;
}//InsertAVL
3、删除
元素的删除,有三种情况,分别是:
(1)被删除的结点是叶子;
(2)被删除的结点只有左子树或者只有右子树;(3)被删除的结点既有左子树,也有右子树。

具体实现如下:
int DeleteAVL(BSTree &p,int x,int &shorter) {
int k;
BSTree q;
if(p==NULL)
{
printf("不存在要删除的关键字!!\n");
return 0;
}
else if(x<p->data)//在p的左子树中进行删除
{
k=DeleteAVL(p->lchild,x,shorter);
if(shorter==1)
LeftBalance_div(p,shorter);
return k;
}
else if(x>p->data)//在p的右子树中进行删除
{
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;
}
}
(三)数据结构
本实验中平衡二叉树采用二叉链表的方式进行存储。

定义如下:
typedef struct BSTNode
{
int data;
int bf; //结点的平衡因子
struct BSTNode *lchild,*rchild;//左、右孩子指针
}BSTNode,*BSTree;
(四)程序结构与流程
本程序包括四个模块,分别为主函数、AVL的创建、AVL的查找函数、AVL的插入函数、AVL的删除函数。

流程图如下:
主函数
void main()
AVL的创建AVL的查找AVL的插入AVL的删除
主函数定义如下:
主函数主要是根据输入的数字选择要对平衡二叉树进行的操作,创建、查找、删除或者是插入。

void main()
{
int input,search;
bool taller=false;
int shorter=0;
BSTree T,T1,T2;
T=(BSTree)malloc(sizeof(BSTNode));
T=T1=T2=NULL;
while(1)
{
printf("1.创建\t2.查找\t3.插入\t4.删除\t5.退出*\n");
printf("请输入您所需的操作功能:\t");
scanf("%d",&input);
getchar();
switch(input)
{
case 1:
CreatBST(T); break;
case 2:
printf("请输入你要查找的关键字");
scanf("%d",&search); getchar();
if(SearchBST(T,search)) printf("该二叉树中存在关键字%d,查找成功!\n",search);
else printf("查找失败!\n");
break;
case 3:
printf("请输入你要插入的关键字");
scanf("%d",&search); getchar();
InsertAVL(T,search,taller);
PrintBST(T); break;
case 4:
printf("请输入你要删除的关键字");
scanf("%d",&search); getchar();
DeleteAVL(T,search,shorter);
PrintBST(T); break;
case 5:
break;
default:printf("输入错误,请重新选择。

");break;
}
printf("\t\t按任意键继续..."); getchar();
}
}
运行平台及开发工具
该程序在Windows XP/07上运行良好,使用Microsoft Visual C++ 6.0开发。

I/O格式
输入:该程序要求输入数据为整型数据,并以-1作为输入数据的结束标志,创建过程中若输入相同的数据只会生成一个关键字并给出输入数据相同的提示。

输出:该程序对于对平衡二叉树的输出采用中序遍历的方法。

因为中序遍历平衡二叉树的得到的结果肯定为有序的,所以可以据此判断对于平衡二叉树操作的正确性。

测试数据:
1、创建
输入数据:34、45、12、22、34、56、76、11、-45、23、-1;进行平衡二叉树的创建,运行结果如下图:
2、查找
①查找在原有二叉树上已存在的关键字:
【查找23】运行结果:
②查找在原有二叉树上不存在的数据:
【查找24】运行结果:
3、插入
在1的基础上进行插入,分两种情况:
①插入与原二叉树关键字不重复的数据:【插入99】运行结果如下:
②插入已存在原二叉树中的数据:
【插入22】运行结果如下:
4、删除
①删除在原有平衡二叉树上已存在的关键字:【删除22】运行结果如下:
②删除在原有平衡二叉树上不存在的数据:【删除98】运行结果如下:
算法复杂度分析
在平衡二叉树上进行查找的过程和二叉排序树相同,因此,在查找的过程中与给定值进行比较的关键字个数不会超过数的深度。

因此平衡二叉树查找的时间复杂度主要由树的深度决定。

我们首先分析深度为h的平衡树所具有的最少结点数。

假设以N(h)表示深度为h的平衡树含有的最少结点数,显然,N(0)=0,N(1)=1,N(2)=2,并且N(h)=N(h-1)+N(h-2),在通过归纳法可以求出这个N(h),反之,在知道n的情况我们也可以推导出h的最大值,所以最后可以得到在平衡二叉树上查找的时间复杂度是T(n)=O(㏒2n)。

同样的插入和删除的时间复杂度也为O(㏒2n)。

源代码
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)>(b))
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
#define NULL 0
typedef struct BSTNode
{
int data;
int bf; //结点的平衡因子
struct BSTNode *lchild,*rchild;//左、右孩子指针
}BSTNode,*BSTree;
void R_Rotate(BSTree &p); //对以*p为根的二叉排序树作右旋处理
void L_Rotate(BSTree &p); //对以*p为根的二叉排序树作左旋处理
void LeftBalance(BSTree &T); //对以指针T所指结点为根的二叉树作左平衡旋转处理void RightBalance(BSTree &T);//对以指针T所指结点为根的二叉树作右平衡旋转处理bool InsertAVL(BSTree &T,int e,bool &taller);//插入结点e
bool SearchBST(BSTree &T,int key);//查找元素key是否在树T中
void PrintBST(BSTree T);//按中序遍历输出二叉树的元素
void CreatBST(BSTree &T); //创建平衡二叉树,(注意:以输入-1为二叉树建立的结束) 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 main()
{
int input,search;
bool taller=false;
int shorter=0;
BSTree T,T1,T2;
T=(BSTree)malloc(sizeof(BSTNode));
T=T1=T2=NULL;
while(1)
{
printf("1.创建\t2.查找\t3.插入\t4.删除\t5.退出*\n");
printf("请输入您所需的操作功能:\t");
scanf("%d",&input);
getchar();
switch(input)
{
case 1:
CreatBST(T); break;
case 2:
printf("请输入你要查找的关键字");
scanf("%d",&search); getchar();
if(SearchBST(T,search)) printf("该二叉树中存在关键字%d,查找成功!\n",search);
else printf("查找失败!\n");
break;
case 3:
printf("请输入你要插入的关键字");
scanf("%d",&search); getchar();
InsertAVL(T,search,taller);
PrintBST(T); break;
case 4:
printf("请输入你要删除的关键字");
scanf("%d",&search); getchar();
DeleteAVL(T,search,shorter);
PrintBST(T); break;
case 5:
break;
default:printf("输入错误,请重新选择。

");break;
}
printf("\t\t按任意键继续..."); getchar();
}
}
//对以*p为根的二叉排序树作右旋处理,LL型平衡旋转法void R_Rotate(BSTree &p)
{
BSTree lc;
lc = p->lchild; //lc指向的*p左子树根结点
p->lchild = lc->rchild; //lc的右子树挂接为*p的左子树lc->rchild = p;
p = lc; //p指向新的结点
}
//对以*p为根的二叉排序树作左旋处理,RR型平衡旋转法void L_Rotate(BSTree &p)
{
BSTree rc;
rc = p->rchild; //rc指向的*p右子树根结点
p->rchild = rc->lchild; //rc的左子树挂接为*p的右子树rc->lchild = p;
p = rc; //p指向新的结点
}
//对以指针T所指结点为根的二叉树作左平衡旋转处理,LR型平衡旋转法void LeftBalance(BSTree &T)
{
BSTree lc,rd;
lc = T->lchild; //lc指向*T的左子树根结点
switch(lc->bf) //检查*T的左子树的平衡度,并作相应平衡处理
{
case LH: //新结点插入在*T的左孩子的左子树上,要作单右旋处理T->bf = lc->bf = EH;
R_Rotate(T); break;
case RH: //新结点插入在*T的左孩子的右子树上,要作双旋处理rd = lc->rchild; //rd指向*T的左孩子的右子树根
switch(rd->bf) //修改*T及其左孩子的平衡因子
{
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); //对*T的左子树作左旋平衡处理
R_Rotate(T); //对*T作右旋平衡处理
}
}
//对以指针T所指结点为根的二叉树作右平衡旋转处理,RL型平衡旋转法void RightBalance(BSTree &T)
{
BSTree rc,ld;
rc = T->rchild; //rc指向*T的右子树根结点
switch(rc->bf) //检查*T的右子树的平衡度,并作相应平衡处理
{
case RH: //新结点插入在*T的右孩子的右子树上,要作单左旋处理T->bf = rc->bf =EH;
L_Rotate(T); break;
case LH: //新结点插入在*T的右孩子的左子树上,要作双旋处理ld = rc->lchild; //ld指向*T的右孩子的左子树根
switch(ld->bf) //修改*T及其右孩子的平衡因子
{
case LH: T->bf = EH; rc->bf = RH; break;
case EH: T->bf = rc->bf =EH; break;
case RH: T->bf = LH; rc->bf = EH; break;
}
ld->bf = EH;
R_Rotate(T->rchild);//对*T的右子树作左旋平衡处理
L_Rotate(T); //对*T作左旋平衡处理
}
}
//插入结点e,若T中不存在和e相同关键字的结点,则插入一个数据元素为e的新结点,并返回1,否则返回0
bool InsertAVL(BSTree &T,int e,bool &taller)
{
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;
}
}
}
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;
}
}
}
}
return 1;
}//InsertAVL
//查找元素key是否在树T中
bool SearchBST(BSTree &T,int key)
{
if(!T) return false;
else if(EQ(key,T->data)) return true;
else if(LT(key,T->data)) return SearchBST(T->lchild,key);
else return SearchBST(T->rchild,key);
}
//中序遍历平衡二叉树
void PrintBST(BSTree T)
{
if(T)
{
PrintBST(T->lchild);
printf(" %d ",T->data);
PrintBST(T->rchild);
}
}
//创建平衡二叉树,(注意:以输入-1为二叉树建立的结束)void CreatBST(BSTree &T)
{
int e;
bool taller=false;
T = NULL;
printf("\n请输入关键字(以-1结束建立平衡二叉树):");
scanf("%d",&e);getchar();
while(e != -1)
{
InsertAVL(T,e,taller);
printf("\n请输入关键字(以-1结束建立平衡二叉树):");
scanf("%d",&e);getchar();taller=false;
}
printf("平衡二叉树创建结束,中序遍历平衡二叉树:\n");
if(T) PrintBST(T);
else printf("这是一棵空树.\n");
}
//删除结点时左平衡旋转处理
void LeftBalance_div(BSTree &p,int &shorter)
{
BSTree p1,p2;
if(p->bf==1) //p结点的左子树高,删除结点后p的bf减1,树变矮
{
p->bf=0; shorter=1;
}
else if(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减1,树高不变
{
p->bf=-1; shorter=0;
}
else //p结点的右子树高
{
p1=p->rchild;//p1指向p的右子树
if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变
{
L_Rotate(p);
p1->bf=1;
p->bf=-1;
shorter=0;
}
else if(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮
{
L_Rotate(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 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)//在p的左子树中进行删除
{
k=DeleteAVL(p->lchild,x,shorter);
if(shorter==1)
LeftBalance_div(p,shorter);
return k;
}
else if(x>p->data)//在p的右子树中进行删除
{
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;
}
}
小结
在完成作业的过程中对于平衡二叉树的定义、创建、查找、插入和删除的算法思想有了更多的了解。

由于其中的一些模块的函数在书上是有范例的,因此可以了解书上的算法之后自己理解之后再尝试写出来。

同时,在这过程中,可以体会到平衡二叉树在查找上的优势,
但是由于平衡二叉树在插入和删除之后都要进行相应的旋转,所以最初的时候理解起来还是有一些难度,不过经过资料的查阅,这个困难也渐渐被克服。

但是有一个遗憾是平衡二叉树的输出函数没能采用树形输出的方式,而是采用中序遍历的方法,不够直观。

同时,没有采用图形界面进行更为直观的输出和表示也是遗憾之一。

也许这个题目对于三个人一起完成看上去简单了一些,但是在这个过程中我们更好地学会了怎么去学习和合作,对于我们来说也是一次难得的经历。

相关文档
最新文档