文档库 最新最全的文档下载
当前位置:文档库 › 平衡二叉树

平衡二叉树

平衡二叉树
平衡二叉树

二叉树:

左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“平衡二叉树”。

平衡二叉树:定义:平衡二叉树或为空树,或为如下性质的二叉排序树:

(1)左右子树深度之差的绝对值不超过1;

(2)左右子树仍然为平衡二叉树.

平衡因子:平衡因子bf=左子树深度-右子树深度,

每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。增加一个元素后,平衡二叉树有可能变成不平衡了,所以需要旋转平衡调整。

平衡二叉树算法思想:

若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于1的结点作为根的子树。假设用A表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况:(可以断定插入一个节点一定是在叶子节点上)

(1)LL型平衡旋转法

由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行一次顺时针旋转操作。即将A的左孩子B向右上旋转代替A作为根结点,A向右下旋转成为B 的右子树的根结点。而原来B的右子树则变成A的左子树。

(2)RR型平衡旋转法

由于在A的右孩子C 的右子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行一次逆时针旋转操作。即将A的右孩子C向左上旋转代替A作为根结点,A向左下旋转成为C 的左子树的根结点。而原来C的左子树则变成A的右子树。

(3)LR型平衡旋转法

由于在A的左孩子B的右子数上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行两次旋转操作(先逆时针,后顺时针)。即先将A结点的左孩子B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。即先使之成为LL 型,再按LL型处理。

如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为LL型,再按LL型处理成平衡型。

(4)RL型平衡旋转法

由于在A的右孩子C的左子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行两次旋转操作(先顺时针,后逆时针),即先将A结点的右孩子C的左子树的根结点D向右上旋转提升到C结点的位置,然后再把该D结点向左上旋转提升到A结点的位置。即先使之成为RR 型,再按RR型处理。

如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到A的左子树上,此时成为RR型,再按RR型处理成平衡型。

平衡化靠的是旋转。参与旋转的是3个节点(其中一个可能是外部节点NULL),旋转就是把这3个节点转个位置。

注意的:左旋的时候p->right一定不为空,右旋的时候p->left一定不为空,这是显而易见的。

如果从空树开始建立,并时刻保持平衡,那么不平衡只会发生在插入删除操作上,而不平衡的标志就是出现bf == 2或者bf == -2的节点。

插入和删除:

插入删除是互为镜像的操作。我们可以采用前面对二叉排序树的删除操作来进行。然后,在删除掉结点后,再对平衡树进行平衡化处理。删除之所以删除操作需要的平衡化可能比插入时次数多,就是因为平衡化不会增加子树的高度,但是可能会减少子树的高度,在有有可能使树增高的插入操作中,一次平衡化能抵消掉增高;在有可能使树减低的删除操作中,平衡化可能会带来祖先节点的不平衡。AVL树体现了一种平衡的美感,两种旋转是互为镜像的,插入删除是互为镜像的操作,没理由会有那么大的差别。实际上,平衡化可以统一的这样来操作:

①查找:先按关键字找到删除的节点*p

②删除:分为:1.叶子节点:直接删除该节点

2.单分子节点:用*p节点的左边或右孩子节点替代*p

3.双分子节点:①用*p节点的左子树的最右下节点*r的值替代*p节点值,②用*p

节点的右子数的最左下节点*r的值替代*p节点的值,再删除*r节点

③调整:

1、while (current != NULL)修改current的平衡因子。

(1)插入节点时current->bf += (current->data > *p)?1:-1;

(2)删除节点时current->bf -= (current->data > *p)?1:-1;

(3)current指向插入节点或者实际删除节点的父节点,这是普通二叉搜索树的插入和删除操作带来的结果。*p初始值是插入节点或者实际删除节点的data。因为删除操作可能实际删除的不是data。

2、判断是否需要平衡化

if (current->bf == -2) L_Balance(c_root);

else if (current->bf == 2) R_Balance(c_root);

3、是否要继续向上修改父节点的平衡因子

(1)插入节点时if (!current->bf) break;这时,以current为根的子树的高度和插入前的高度相同。(2)删除节点时if (current->bf) break;这时,以current为根的子树的高度和删除前的高度相同

4、当前节点移动到父节点,转1。

p = &(current->data); current = current->parent;

习题分析:

1.含有n个节点的平衡二叉树的最大高度为O(log2n)

2.设N h表示高度为h的平衡二叉树中含有的最少节点数:有N1=1、N2=2、N h=N h-1+N h-2+1

3.已知节点个数N,有N1=1、N2=2、N h=N h-1+N h-2+1,可以求出树的最大高度,

4.在一棵高度为h(h≧3)的平衡二叉树,最小叶子节点所在层次为h,最小叶子节点所在层次为min(h),显然有,min(1)=1,min(2)=2,min(1)={min(h-1),min(h-2)}+1

5.查找比较关键字序列:设含有n个节点的平衡二叉树,1.求出其最大高度,和叶子节点最小层数,则比较次数最大为最大高度值其一定能找到该节点(存在),所以序列个数一定小于最大高度大于或等于叶子节点最小层数 2.符合二叉排序树排序,用此排除一些选项

五、相关代码实现

1.基本结构体及变量

#define LH +1 // 左高

#define EH 0 // 等高

#define RH -1 // 右高

// 平衡二叉树的类型

struct A VLNode

{

int data;

int bf; //bf结点的平衡因子,只能够取0,-1,1,为左子树的深度减去右子树的深度

struct AVLNode *lchild,*rchild; // 左、右孩子指针

};

2.右旋操作:

void R_Rotate(A VLNode *&p) // LL型算法

{

A VLNode *lc=p->lchild; // lc指向p的左子树根结点

p->lchild=lc->rchild; // lc的右子树挂接为p(之前跟节点)的左子树

lc->rchild=p;

p=lc; // p指向新的根结点

}

3.左旋操作:

void L_Rotate(A VLNode *&p) // RR型算法

{

A VLNode *rc=p->rchild; // rc指向p的右子树根结点

p->rchild=rc->lchild; // rc的左子树挂接为p的右子树

rc->lchild=p;

p=rc; // p指向新的根结点

}

4.对树进行左平衡操作:

void LeftBalance(A VLNode *&T)

{

A VLNode *lc,*rd;

lc=T->lchild; // lc指向T的左子树根结点

switch(lc->bf) // 1为左高、0等高、-1为右高

{

case LH: // 1 新结点插入在*T的左孩子的左子树上,要作单右旋处理T->bf=lc->bf=EH;

R_Rotate(T);

break;

case RH: // -1 新结点插入在*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;

}

rd->bf=EH;

L_Rotate(T->lchild);

R_Rotate(T);

}

}

5.对树进行右平衡操作:

void RightBalance(A VLNode *&T)

{

A VLNode *rc,*rd;

rc=T->rchild;

switch(rc->bf)

{

case RH:

T->bf=rc->bf=EH;

L_Rotate(T);

break;

case LH:

rd=rc->lchild;

switch(rd->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;

}

rd->bf=EH;

R_Rotate(T->rchild);

L_Rotate(T);

}

}

6.插入操作:

int InsertAVL(AVLNode *&T,int data,int *taller)

{

if(!T) //此时为初始情况或已找到适当位置插入新数据

{

T=(A VLNode *)malloc(sizeof(A VLNode));

T->data=data;

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

T->bf=EH;

*taller=1;

}

else {

if(data == T->data)

{

*taller=0;

return 0;

}

if(data < T->data)

{

if(!InsertA VL(T->lchild,data,taller))

return 0;

if(*taller)

switch(T->bf)

{

case LH: //插入前做左子树比右子树高,插入后,左子树已经长高, 排序树失去平衡

LeftBalance(T); //对排序树进行右平衡操作

*taller=0;

break;

case EH:

T->bf=LH;

*taller=1; //这里标识有所长高实际上此时父节点或者祖父结点的平衡因子的绝对值已经大于1

break;

case RH: //插入前右子树比左子树高,插入后左右子树深度相等

T->bf=EH;

*taller=0; //标志没长高

}

}

else {

if(!InsertA VL(T->rchild,data,taller))

return 0;

if(*taller)

switch(T->bf)

{ //插入前左子树比右子树高,插入后左右子树深度相等

case LH:

T->bf=EH; //标志没长高

*taller=0;

break;

case EH: //这里标识有所长高实际上此时父节点或者祖父节点的平衡因子的绝对值已经大于1

T->bf=RH;

*taller=1;

break;

case RH: //插插入前做右子树比左子树高,插入后,右子树已经长高, 排序树失去平衡

RightBalance(T); //对排序树进行右平衡操作

*taller=0;

}

}

}

return 1;

}

平衡二叉树的生成过程

二叉排序树变成平衡二叉树 对于二叉查找树,尽管查找、插入及删除操作的平均运行时间为O(logn),但是它们的最差运行时间都是O(n),原因在于对树的形状没有限制。 平衡二叉树又称为AVL树,它或者是一棵空树,或者是有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左右子树的深度之差的绝对值不超过1。二叉树的的平衡因子BF为:该结点的左子树的深度减去它的右子树的深度,则平衡二叉树的所有结点的平衡因子为只可能是:-1、0和1 一棵好的平衡二叉树的特征: (1)保证有n个结点的树的高度为O(logn) (2)容易维护,也就是说,在做数据项的插入或删除操作时,为平衡树所做的一些辅助操作时间开销为O(1) 一、平衡二叉树的构造 在一棵二叉查找树中插入结点后,调整其为平衡二叉树。若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树 1.调整方法 (1)插入点位置必须满足二叉查找树的性质,即任意一棵子树的左结点都小于根结点,右结点大于根结点 (2)找出插入结点后不平衡的最小二叉树进行调整,如果是整个树不平衡,才进行整个树的调整。 2.调整方式 (1)LL型 LL型:插入位置为左子树的左结点,进行向右旋转(LL表示的是在做子树的左结点进行插入) 由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1变为2,成为不平衡的最小二叉树根结点。此时A结点顺时针右旋转,旋转过程中遵循“旋转优先”的规则,A结点替换D结点成为B结点的右子树,D结点成为A结点的左孩子。 (2)RR型

数据结构程序报告(平衡二叉树的操作)

计算机科学学院数据结构课程设计报告 平衡二叉树操作 学生姓名: 学号: 班级: 指导老师: 报告日期:

1.需求分析 1.建立平衡二叉树并进行创建、查找、插入、删除等功能。 2.设计一个实现平衡二叉树的程序,可进行创建、查找、插入、删除等操作,实现动态的输入数据,实时的输出该树结构。 3.测试数据:自选数据 2.概要设计 1.抽象数据类型定义: typedef struct BSTNode { int data; int bf; //节点的平衡因子 struct BSTNode *lchild,*rchild; //左右孩子指针 }BSTNode,*BSTree; void CreatBST(BSTree &T); //创建平衡二叉树 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 LeftBalance_div(BSTree &p,int &shorter); //删除结点时左平衡旋转处理 void RightBalance_div(BSTree &p,int &shorter); //删除结点时右平衡旋转处理 void Delete(BSTree q,BSTree &r,int &shorter); //删除结点 int DeleteA VL(BSTree &p,int x,int &shorter); //平衡二叉树的删除操作 void PrintBST(BSTree T,int m); //按树状打印输出二叉树的元素 2.主程序的流程 3.各模块之间的层次调用

数据结构平衡二叉树的操作演示

平衡二叉树操作的演示 1.需求分析 本程序是利用平衡二叉树,实现动态查找表的基本功能:创建表,查找、插入、删除。具体功能: (1)初始,平衡二叉树为空树,操作界面给出创建、查找、插入、删除、合并、分裂六种操作供选择。每种操作均提示输入关键字。每次插入或删除一个结点后,更 新平衡二叉树的显示。 (2)平衡二叉树的显示采用凹入表现形式。 (3)合并两棵平衡二叉树。 (4)把一棵二叉树分裂为两棵平衡二叉树,使得在一棵树中的所有关键字都小于或等于x,另一棵树中的任一关键字都大于x。 如下图: 2.概要设计 平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

具体步骤: (1)每当插入一个新结点,从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子,若该结点的祖先结点的平衡因子的绝对值不超过1,则平衡二叉树没有失去平衡,继续插入结点; (2)若插入结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点; (3)判断新插入的结点与最小不平衡子树的根结点个关系,确定是那种类型的调整;(4)如果是LL型或RR型,只需应用扁担原理旋转一次,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;如果是LR型或RL型,则需应用扁担原理旋转两次,第一次最小不平衡子树的根结点先不动,调整插入结点所在子树,第二次再调整最小不平衡子树,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;(5)计算调整后的平衡二叉树中各结点的平衡因子,检验是否因为旋转而破坏其他结点的平衡因子,以及调整后平衡二叉树中是否存在平衡因子大于1的结点。 流程图 3.详细设计 二叉树类型定义: typedef int Status; typedef int ElemType; typedef struct BSTNode{

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

平衡二叉树(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为根的二叉排序树作右旋处理

平衡二叉树操作演示

数据结构实习报告 题目:平衡二叉树的操作演示 班级:信息管理与信息系统11-1 姓名:崔佳 学号:201101050903 完成日期:2013.06.25

一、需求分析 1. 初始,平衡二叉树为空树,操作界面给出两棵平衡二叉树的显示、查找、插入、删除、销毁、合并两棵树,几种选择。其中查找、插入和删除操作均要提示用户输入关键字。每次插入或删除一个节点后都会更新平衡二叉树的显示。 2. 平衡二叉树的显示采用凹入表形式。 3.每次操作完毕后都会给出相应的操作结果,并进入下一次操作,知道用户选择退出 二、概要设计 1.平衡二叉树的抽象数据类型定义: ADT BalancedBinaryTree{ 数据对象D:D是具有相同特性的数据元素的集合。各个数据元素均含有类型相同,可唯一标志的数据元素的关键字。 数据关系R:数据元素同属一个集合。 基本操作P: InitAVL(BSTree& T) 操作结果:构造一个空的平衡二叉树T DestroyAVL(BSTree& T) 初始条件:平衡二叉树T存在 操作结果:销毁平衡二叉树T SearchAVL(BSTree T,int key) 初始条件:平衡二叉树T存在,key为和关键字相同类型的给定值 操作结果:若T中存在关键字和key相等的数据元素,则返回指向该元素的 指针,否则为空 InsertAVL(BSTree& T,int key,Status& taller) 初始条件:平衡二叉树T存在,key和关键字的类型相同 操作结果:若T中存在关键字等于key的数据元素则返回,若不存在则插入 一个关键字为key的元素 DeleteAVL(BSTree& T,int &key,Status& lower) 初始条件:平衡二叉树T存在,key和关键字的类型相同 操作结果:若T中存在关键字和key相同的数据元素则删除它}ADT BalancedBinaryTree

平衡二叉树 构造方法(绝妙)

平衡二叉树构造方法 平衡二叉树 对于二叉查找树,尽管查找、插入及删除操作的平均运行时间为O(logn),但是它们的最差运行时间都是O(n),原因在于对树的形状没有限制。 平衡二叉树又称为AVL树,它或者是一棵空树,或者是有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左右子树的深度之差的绝对值不超过1。二叉树的的平衡因子BF为:该结点的左子树的深度减去它的右子树的深度,则平衡二叉树的所有结点的平衡因子为只可能是:-1、0和1 一棵好的平衡二叉树的特征: (1)保证有n个结点的树的高度为O(logn) (2)容易维护,也就是说,在做数据项的插入或删除操作时,为平衡树所做的一些辅助操作时间开销为O(1) 一、平衡二叉树的构造 在一棵二叉查找树中插入结点后,调整其为平衡二叉树。若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树 1.调整方法 (1)插入点位置必须满足二叉查找树的性质,即任意一棵子树的左结点都小于根结点,右结点大于根结点 (2)找出插入结点后不平衡的最小二叉树进行调整,如果是整个树不平衡,才进行整个树的调整。 2.调整方式 (1)LL型 LL型:插入位置为左子树的左结点,进行向右旋转

由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1变为2,成为不平衡的最小二叉树根结点。此时A结点顺时针右旋转,旋转过程中遵循“旋转优先”的规则,A结点替换D结点成为B结点的右子树,D结点成为A结点的左孩子。 (2)RR型 RR型:插入位置为右子树的右孩子,进行向左旋转 由于在A的右子树C的右子树插入了结点F,A的平衡因子由-1变为-2,成为不平衡的最小二叉树根结点。此时,A结点逆时针左旋转,遵循“旋转优先”的规则,A结点替换D结点成为C的左子树,D结点成为A的右子树。 (3)LR型 LR型:插入位置为左子树的右孩子,要进行两次旋转,先左旋转,再右旋转;第一次最小不平衡子树的根结点先不动,调整插入结点所在的子树,第二次再调整最小不平衡子树。 由于在A的左子树B的右子树上插入了结点F,A的平衡因子由1变为了2,成为不平衡的最小二叉树根结点。第一次旋转A结点不动,先将B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。 (4)RL型 RL型:插入位置为右子树的左孩子,进行两次调整,先右旋转再左旋转;处理情况与LR 类似。

数据结构程序报告(平衡二叉树的操作)

数据结构程序报告(平衡二叉树的操作)

计算机科学学院数据结构课程设计报告 平衡二叉树操作 学生姓名: 学号: 班级: 指导老师: 报告日期:

1.需求分析 1.建立平衡二叉树并进行创建、查找、插入、删除等功能。 2.设计一个实现平衡二叉树的程序,可进行创建、查找、插入、删除等操作,实现动态的输入数据,实时的输出该树结构。 3.测试数据:自选数据 2.概要设计 1.抽象数据类型定义: typedef struct BSTNode { int data; int bf; //节点的平衡因子 struct BSTNode *lchild,*rchild; //左右孩子指针 }BSTNode,*BSTree; void CreatBST(BSTree &T); //创建平衡二叉树 void R_Rotate(BSTree &p); //对以*p 为根的二叉排序树作左旋处理 void L_Rotate(BSTree &p); //对以*p 为根的二叉排序树作左旋处理 void LeftBalance(BSTree &T); //对以指针T所指结点为根的二叉树作左平衡旋转处理void RightBalance(BSTree &T); //对以指针T所指结点为根的二叉树作右平衡旋转处理bool InsertA VL(BSTree &T,int e,bool &taller);

//插入结点e bool SearchBST(BSTree &T,int key); //查找元素key是否在树T中 void LeftBalance_div(BSTree &p,int &shorter); void RightBalance_div(BSTree &p,int &shorter);

平衡二叉树-数据结构课程设计论文【可运行测试】

数据结构课程设计 课程名称:平衡二叉树的生成 院系:信息工程学院 年级专业:10级计科 学号: 学生姓名: 指导教师: 开题时间: 2010 年 12 月 01 日 完成时间: 2010 年 12 月 31 日 信息工程学院

X X X X X X X数据结构课程设计成绩评定表 院系:信息工程学院年级专业: 学号:姓名:

摘要 本篇论文系计科专业10年末课程设计论文,按照相应要求写作而成。 主要讨论的是平衡二叉树的生成问题,借助本程序可以由用户输入数值,并生成平衡二叉树,并可以对数据进行方便的修改和删除添加,任意插入或删除一个结点后仍然要求任然构成平衡二叉树,并按中序遍历输出这棵平衡二叉树。· 本论文共由五个章构成,每个内容独立成章,各章下设相应子章节。 各个章节逐渐递进,分别是: 第一章:需求分析 第二章系统设计 第三章编码 第四章测试 第五章维护 本论文特点: 1.论述清楚,目录详尽,可以方便的查询相应章节,方便使用。 2.图文结合,几乎没一个子程序模块都有相应的流程图与之对应,有利于读者理解每 个子程序的设计思路。 3.模块分化清晰,每个模块独立成节,又彼此联系,深化了C语言模块化编程的特点。 4.测试模块配合对应的运行截图,真实可信,对读者理解程序的运行情况起到了很大 作用。 5.程序清单完整详细,解释详细。

目录 第一章需求分析 (1) 1.1功能描述------------------------------------------------1 1.2数据词典------------------------------------------------1 第二章系统设计 (3) 2.1 基本概念介绍----------------------------------------------3 2.2 总体设计--------------------------------------------------8 2.3 插入结点-------------------------------------------------10 2.4 删除结点-------------------------------------------------11 2.5 中序遍历-------------------------------------------------11 第三章编码 (12) 3.1 总体编码------------------------------------------------12 3.2 总流程图------------------------------------------------15 3.3 以指针T所指结点为根的二叉树作右平衡旋转处理------------16 第四章测试 (17) 4.1 创建二叉树测试-------------------------------------------17 4.2 插入结点测试---------------------------------------------19 4.3 删除结点测试---------------------------------------------20 4.4中序遍历结点测试------------------------------------------21 4.5 先序遍历测试---------------------------------------------21 第五章维护 (22) 5.1维护----------------------------------------------------22

二叉排序树与平衡二叉树的实现课程设计

攀枝花学院本科学生课程设计任务书题目二叉排序树与平衡二叉树的实现 1、课程设计的目的 1)使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操 作实现算法,以及它们在程序中的使用方法。 2)使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力。 3)使学生掌握使用各种计算机资料和有关参考资料,提高学生进行程序设计的基本能力。 2、课程设计的内容和要求(包括原始数据、技术要求、工作要求等) 1) (1)以回车('\n')为输入结束标志,输入数列L,生成一棵二叉排序树T; (2)对二叉排序树T作中序遍历,输出结果; (3)计算二叉排序树T查找成功的平均查找长度,输出结果; (4)输入元素x,查找二叉排序树T,若存在含x的结点,则删该结点,并作中序遍历(执行 操作2);否则输出信息“无x”; (5)用数列L,生成平衡的二叉排序树BT:当插入新元素之后,发现当前的二叉排序树BT 不是平衡的二叉排序树,则立即将它转换成新的平衡的二叉排序树BT; (6)计算平衡的二叉排序树BT的平均查找长度,输出结果。 3、主要参考文献 [1]刘大有等,《数据结构》(C语言版),高等教育出版社 [2]严蔚敏等,《数据结构》(C语言版),清华大学出版社 [3]William Ford,William Topp,《Data Structure with C++》清华大学出版社 [4]苏仕华等,数据结构课程设计,机械工业出版社 4、课程设计工作进度计划 第1天完成方案设计与程序框图 第2、3天编写程序代码 第4天程序调试分析和结果 第5天课程设计报告和总结 指导教师(签字)日期年月日 教研室意见: 年月日学生(签字): 接受任务时间:年月日注:任务书由指导教师填写。

平衡二叉树

二叉树: 左子树都小于根节点,右子树都大于根节点。可以动态维护这棵树(因为是树结构,可以有限步完成插入),所以是动态查找算法。时间复杂度为O(logn)在46.5%的情况下,需要把二叉树平衡化成“平衡二叉树”。 平衡二叉树:定义:平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树仍然为平衡二叉树. 平衡因子:平衡因子bf=左子树深度-右子树深度, 每个结点的平衡因子只能是1,0,-1。若其绝对值超过1,则该二叉排序树就是不平衡的。增加一个元素后,平衡二叉树有可能变成不平衡了,所以需要旋转平衡调整。 平衡二叉树算法思想: 若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于1的结点作为根的子树。假设用A表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况:(可以断定插入一个节点一定是在叶子节点上) (1)LL型平衡旋转法 由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1增至2而失去平衡。故需进行一次顺时针旋转操作。即将A的左孩子B向右上旋转代替A作为根结点,A向右下旋转成为B 的右子树的根结点。而原来B的右子树则变成A的左子树。 (2)RR型平衡旋转法 由于在A的右孩子C 的右子树上插入结点F,使A的平衡因子由-1减至-2而失去平衡。故需进行一次逆时针旋转操作。即将A的右孩子C向左上旋转代替A作为根结点,A向左下旋转成为C 的左子树的根结点。而原来C的左子树则变成A的右子树。

数据结构课程设计-_平衡二叉树操作

课程设计报告 课程名称数据结构课程设计 题目平衡二叉树操作 指导教师 设计起止日 2010-5-16 学院计算机学院 专业软件工程 学生姓名 班级/学号------------ 成绩_________________

一.需求分析 1、建立平衡二叉树并进行创建、增加、删除、调平等操作。 2、设计一个实现平衡二叉树的程序,可进行创建、增加、删除、调平等操作,实现动态的输入数据,实时的输出该树结构。 3、测试数据:自选数据 二.概要设计 平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。具体步骤如下: ⑴每当插入一个新结点,从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子,若该结点的祖先结点的平衡因子的绝对值均不超过1,则平衡二叉树没有失去平衡,继续插入结点; ⑵若插入结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点; ⑶判断新插入的结点与最小不平衡子树的根结点的关系,确定是哪种类型的调整; ⑷如果是LL型或RR型,只需应用扁担原理旋转一次,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;如果是LR型或RL型,则需应用扁担原理旋转两次,第一次最小不平衡子树的根结点先不动,调整插入结点所在子树,第二次再调整最小不平衡子树,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突; ⑸计算调整后的平衡二叉树中各结点的平衡因子,检验是否因为旋转而破坏其他结点的平衡因子,以及调整后的平衡二叉树中是否存在平衡因子大于1的结点。 三.详细设计 树的内部变量 typedef struct BTNode {

平衡二叉树调整算法

平衡二叉树调整算法 在平衡二叉树中插入一个结点后造成不平衡,设最低的不平衡结点为A,并已知A的左孩子平衡因子为0,右孩子平衡因子为1,则应该做(C)型调整以使其平衡 A LL B LR C RL D RR 若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树。 失去平衡的最小子树是指以离插入结点最近,且平衡因子绝对值大于 1 的结点作为根的子树。假设用 A 表示失去平衡的最小子树的根结点,则调整该子树的操作可归纳为下列四种情况。 (1)LL型平衡旋转法 由于在 A 的左孩子 B 的左子树上插入结点 F ,使 A 的平衡因子由 1 增至2 而失去平衡。故需进行一次顺时针旋转操作。即将 A 的左孩子 B 向右上旋转代替 A 作为根结点, A 向右下旋转成为 B 的右子树的根结点。而原来B 的右子树则变成 A 的左子树。 (2)RR型平衡旋转法 由于在 A 的右孩子 C 的右子树上插入结点 F ,使 A 的平衡因子由-1 减至-2 而失去平衡。故需进行一次逆时针旋转操作。即将 A 的右孩子 C 向

左上旋转代替 A 作为根结点, A 向左下旋转成为 C 的左子树的根结点。而原来C 的左子树则变成 A 的右子树。 (3)LR型平衡旋转法 由于在 A 的左孩子 B 的右子数上插入结点 F ,使 A 的平衡因子由 1 增至2 而失去平衡。故需进行两次旋转操作(先逆时针,后顺时针)。即先将A 结点的左孩子B 的右子树的根结点 D 向左上旋转提升到 B 结点的位置,然后再把该D 结点向右上旋转提升到 A 结点的位置。即先使之成为LL型,再按LL型处理。 如图中所示,即先将圆圈部分先调整为平衡树,然后将其以根结点接到 A 的左子树上,此时成为LL 型,再按LL 型处理成平衡型。 (4)RL型平衡旋转法 由于在 A 的右孩子 C 的左子树上插入结点 F ,使 A 的平衡因子由-1 减至-2 而失去平衡。故需进行两次旋转操作(先顺时针,后逆时针),即先将A 结点的右孩子C 的左子树的根结点D 向右上旋转提升到C 结点的位置,然后再把该D 结点向左上旋转提升到 A 结点的位置。即先使之成为RR型,

数据结构课程设计:平衡二叉树

数据结构课程设计:平衡二叉树 目录 1 课程设计的目的和内容.............................................. 1 课程设计目的 ................................................ 1 1.1 1.2 主要内容 (1) 2 课程设计分析 (2) 2.1 程序的目的和要求 (2) 2.2 程序的主要数据和功能模块 (2) 3 详细设计 (5) 3.1 程序主要功能模块的伪代码算法 (5) 3.2 程序主要流程图 (8) 4 测试数据与测试结果................................................ 9 5 程序的使用和改进. (14) 5.1 用户使用说明 (14) 5.2 程序的改进 (14) 6 课程设计小结..................................................... 15 7 参考文献 (15) 1 平衡二叉树 1 课程设计的目的和内容 1.1 课程设计目的 复习二叉树的三叉链表存储结构和遍历方法。 掌握二叉排序树的特点和生成方法。

掌握平衡二叉树四种不平衡形态的判定和旋转为平衡的方法。 1.2 主要内容 (1)输入结点数据,构造二叉树的结点,按二叉排序树的规则插入该结点到三叉链表中; (2)通过插入函数InsertAVL(BSTNode* &T,int key)插入新结点到二叉树中,并递归调用插入函数本身,直到正确插入到二叉树中,并返回上次递归,每返回上次递归一次同时判断其平衡度bf,找到最小不平衡树的根结点p。 (3)判断最小不平衡树的平衡因子(bf)的值,若bf>1, 则调用左平衡函数LeftBalance(),若bf<-1,则调用右平衡函RightBalance(),再判断根结点p的左(右)孩子的平衡因子(共有LL型、LR型、RR型、RL型四种),然后判定得到的不平衡形态调用不同的旋转函数即可将其重新调整为平衡二叉树; (4)重复步骤(1)(2)(3),直到所有结点都插入到该平衡二叉树中为止; (5)输出该二叉树的前序(或者后序)序列和中序序列,手工恢复出该二叉树,检验其是否为平衡二叉树;并验证其中序序列的有序性。 2 平衡二叉树 2 课程设计分析 2.1 程序的目的和要求 (1)本程序演示平衡二叉树的插入,以及AVL的前序遍历和中序遍历,并且验证其中序遍历有序性。 (2)对平衡二叉树出现的的的LL,LR,RL,RR四种情况进行处理是其平衡。 (3)接着要实现平衡二叉树的插入,其中根据平衡二叉树插入的算法要不停的把插入的元素平衡地插入,需要判断平衡并调用左右旋转函数,更新平衡二叉树 2.2 程序的主要数据和功能模块 (1)程序主要数据 平衡二叉树左右子树的深度:ldep,rdep

实验报告平衡二叉树

实习报告 一、需求分析 1、问题描述 利用平衡二叉树实现一个动态查找表。 (1)实现动态查找表的三种基本功能:查找、插入和删除。 (2)初始时,平衡二叉树为空树,操作界面给出查找、插入和删除三种操作供选择。每种操作均要提示输入关键字。在查找时,如果查找的关键字不存在,则把其插入到平衡二叉树中。每次插入或删除一个结点后,应更新平衡二叉树的显示。 (3)每次操作的关键字都要从文件中读取,并且关键字的集合限定为短整型数字{1,2,3······},关键字出现的顺序没有限制,允许出现重复的关键字,并对其进行相应的提示。 (4)平衡二叉树的显示采用图形界面画出图形。 2、系统功能 打开数据文件,用文件中的关键字来演示平衡二叉树操作的过程。 3、程序中执行的命令包括: (1)(L)oad from data file //在平衡的二叉树中插入关键字; (2)(A)ppend new record //在平衡的二叉树中查找关键字; (3)(U)pate special record //显示调整过的平衡二叉树; (4)(D)elete special record //删除平衡二叉树中的关键字; (5)(Q)uit //结束。 4、测试数据: 平衡二叉树为: 图 1 插入关键字10之前的平衡二叉树 插入关键字:10; 调整后: 图 2 插入关键字10之后的平衡二叉树 删除关键字:14; 调整后:

图 3 删除关键字14后的平衡二叉树 查找关键字:11; 输出:The data is here! 图 3 查找关键字11后的平衡二叉树 二、概要设计 本次实验目的是为了实现动态查找表的三种基本功能:查找、插入和删除。动态查找表可有不同的表示方法,在此次实验中主要是以平衡二叉树的结构来表示实现的,所以需要两个抽象数据类型:动态查找表和二叉树。 1、动态查找表的抽象数据类型定义为: ADT DynamicSearchTable {数据对象D :D是具有相同特性的数据元素的集合。各个数据元素均含 有类型相同,可唯一标识数据元素的关键字。 数据关系R :数据元素同属于一个集合。 基本操作P : InitDSTable(&ST); 操作结果:构造一个空的动态查找表DT。 DestroyDSTable(&DT);

平衡二叉树算法及代码

Size Balanced Tree Size Balanced Tree(SBT)是一种平衡二叉查找树。它的论文由中国广东中山纪念中学的陈启峰于2006年底完成,并在Winter Camp 2007中发表。由于SBT的拼写很容易找到中文谐音,它常被中国的OIer们戏称为“傻X树”、“Super BT”等。但它的性能并不SB,编写起来也并不BT。恰恰相反,SBT易于实现,且据陈启峰论文中所言,“这是目前为止速度最快的高级二叉搜索树”。它能在O(logn)的时间内完成所有BST的相关操作。而且由于SBT赖以保持平衡的是Size域而不是其他“无用”的域,它可以很方便地实现动态顺序统计中的select和rank。 性质 Size Balanced Tree(SBT)是一种通过大小(Size)域来保持平衡的二叉搜索树,它也因此得名。它总是满足: 对于SBT的每一个结点t: 1. 性质(a) s[right[t] ]≥s[left[left[t]]],s[right[left[t]]] 2. 性质(b) s[left[t] ]≥s[right[right[t]]],s[left[right[t]]] 即每棵子树的大小不小于其兄弟的子树大小。 图1 如图(圈代表结点,三角代表SBT,下同): 1. s[R] ≥s[A],s[B] 2. s[L] ≥s[C],s[D] 旋转 SBT的旋转(Rotations)与其他许多高级BST相同。它是下面提到的Maintain操作的基础。

图2 [编辑]左旋转 右旋转 保持性质(Maintain) 当我们插入或删除一个结点后,SBT的大小就发生了改变。这种改变有可能导致性质(a)或(b)被破坏。这时,我们需要用Maintain操作来修复这棵树。Maintain操作是SBT中最具活力的一个独特过程;Maintain(T)用于修复以T为根的SBT。调用Maintain(T)的前提条件是T的子树都已经是SBT了。 我们需要讨论的有4种情况。由于性质a和性质b是对称的,所以我们仅仅详细的讨论性质a。

平衡二叉树学生信息管理系统程序

#include #include typedef struct A { char NO[10]; char name[10]; char birt[10]; char clas[10]; char sex[2]; }Elemtype; typedef struct B { Elemtype data; int bf; struct B *lchild; struct B *rchild; }node,*pnode; void left1(pnode &ptree,int &taller) { pnode p1,p2; if(ptree->bf==0) { ptree->bf=1; taller=1; } else if (ptree->bf==-1) { ptree->bf=0; taller=0; } else { p1=ptree->lchild; if (p1->bf==1) { ptree->lchild=p1->rchild; p1->rchild=ptree; ptree->bf=p1->bf=0; ptree=p1; } else if (p1->bf==-1)

{ p2=p1->rchild; p1->rchild=p2->lchild; p2->lchild=p1; ptree->lchild=p2->rchild; p2->rchild=ptree; if (p2->bf==0) ptree->bf=p1->bf=0; else if (p2->bf==1) { p1->bf=0; ptree->bf=-1; } else { p1->bf=1; ptree->bf=0; } ptree=p2; ptree->bf=0; } taller=0; } } void right1(pnode &ptree,int &taller) { pnode p1,p2; if(ptree->bf==0) { ptree->bf=-1; taller=1; } else if (ptree->bf==1) { ptree->bf=0; taller=0; } else { p1=ptree->rchild; if (p1->bf==-1) { ptree->rchild=p1->lchild;

平衡二叉树构建过程之我的理解

平衡二叉查找树 构建方法 郭建勇 coolkissmile@https://www.wendangku.net/doc/3e16967828.html,

定义 ?平衡二叉树(全称平衡二叉查找树) –是一棵二叉树 –是一颗二叉查找树 (对于任意节点x, 其左子树的所有节点都小于x, x的右子树的节点都大于等于x) –是一颗平衡树, 平衡意思是对于任意节点, 其左子树高度和右子树高度相差不超过1, 左右子树的高度差称为平衡因子 a, 也即 |a| <=1

辨析 ?平衡二叉树 vs 二叉查找树 二叉查找树也称作二叉排序树或者二叉搜索树 平衡二叉树的本质特点是左右子树的平衡, 而二 叉查找树是不要求平衡的 这也是为什么二叉搜索树在某些极端情况下搜索效率很低的原因: 高度太高, 接近线性效率 平衡二叉树就是为了尽量降低树的高度而提出来的.

插入 ?平衡二叉树的查找逻辑比较简单, 这里不讲了 ?构建平衡二叉树时的逻辑需要深刻理解?插入节点时如果左右子树平衡就不需要调整节点 ?如果左右不平衡那么就需要调整节点 ?由于不平衡没有一个统一的调整策略, 需要分情况看待, 左左, 右右, 左右, 右左.

100 110 ... new 出现不平衡--右右右右不平衡: 首先定位最小不平衡二叉树, 以100为根节点的树 如果新插入节点 new 是在100的右孩子(110)的右子树分支(以120为根的子树) 就称为右右不平衡105 120......

110 ... 105120 ...... new 思路: 把100的右子树高度降低1,或者把100的左子树高度加1 如果能把110为根的树提高到100的位置, 那么右子树高度就降低了1

数据结构课程设计:平衡二叉树

目录 1 课程设计的目的和内容 (1) 1.1 课程设计目的 (1) 1.2 主要内容 (1) 2 课程设计分析 (2) 2.1 程序的目的和要求 (2) 2.2 程序的主要数据和功能模块 (2) 3 详细设计 (5) 3.1 程序主要功能模块的伪代码算法 (5) 3.2 程序主要流程图 (8) 4 测试数据与测试结果 (9) 5 程序的使用和改进 (14) 5.1 用户使用说明 (14) 5.2 程序的改进 (14) 6 课程设计小结 (15) 7 参考文献 (15)

1 课程设计的目的和内容 1.1 课程设计目的 复习二叉树的三叉链表存储结构和遍历方法。 掌握二叉排序树的特点和生成方法。 掌握平衡二叉树四种不平衡形态的判定和旋转为平衡的方法。 1.2 主要内容 (1)输入结点数据,构造二叉树的结点,按二叉排序树的规则插入该结点到三叉链表中; (2)通过插入函数InsertAVL(BSTNode* &T,int key)插入新结点到二叉树中,并递归调用插入函数本身,直到正确插入到二叉树中,并返回上次递归,每返回上次递归一次同时判断其平衡度bf,找到最小不平衡树的根结点p。 (3)判断最小不平衡树的平衡因子(bf)的值,若bf>1, 则调用左平衡函数LeftBalance(),若bf<-1,则调用右平衡函RightBalance(),再判断根结点p的左(右)孩子的平衡因子(共有LL型、LR型、RR型、RL型四种),然后判定得到的不平衡形态调用不同的旋转函数即可将其重新调整为平衡二叉树; (4)重复步骤(1)(2)(3),直到所有结点都插入到该平衡二叉树中为止; (5)输出该二叉树的前序(或者后序)序列和中序序列,手工恢复出该二叉树,检验其是否为平衡二叉树;并验证其中序序列的有序性。

平衡二叉树的生成过程

二叉排序树变成平衡二叉树 莂蚅薈莈羁蚆薅对于二叉查找树,尽管查找、插入及删除操作的平均运行时间为O(logn),但是它们的最差运行时间都是O(n),原因在于对树的形状没有限制。 袅膆薈螃螅莇肀平衡二叉树又称为AVL树,它或者是一棵空树,或者是有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左右子树的深度之差的绝对值不超过1。二叉树的的平衡因子BF为:该结点的左子树的深度减去它的右子树的深度,则平衡二叉树的所有结点的平衡因子为只可能是:-1、0和1 羈羂芁羅腿芀膄一棵好的平衡二叉树的特征: 膁肂膅蚆葿蚂肅(1)保证有n个结点的树的高度为O(logn) 薀芅蒈蕿蒃芅蒅(2)容易维护,也就是说,在做数据项的插入或删除操作时,为平衡树所做的一些辅助操作时间开销为O(1) 蒄肆蝿羁莄芇莁一、平衡二叉树的构造 袈罿螃薄聿蒁莂在一棵二叉查找树中插入结点后,调整其为平衡二叉树。若向平衡二叉树中插入一个新结点后破坏了平衡二叉树的平衡性。首先要找出插入新结点后失去平衡的最小子树根结点的指针。然后再调整这个子树中有关结点之间的链接关系,使之成为新的平衡子树。当失去平衡的最小子树被调整为平衡子树后,原有其他所有不平衡子树无需调整,整个二叉排序树就又成为一棵平衡二叉树 膈莁螄蚇蚁芄蚄1.调整方法 膂袄蒈袀螁袄莅(1)插入点位置必须满足二叉查找树的性质,即任意一棵子树的左结点都小于根结点,右结点大于根结点 肃羆羀薃羄膇芈(2)找出插入结点后不平衡的最小二叉树进行调整,如果是整个树不平衡,才进行整个树的调整。 螈膀肁膃罿蒈羄2.调整方式 莀袃莃薇袂蒂芃(1)LL型 蒀蒃荿肁芄蒃芆LL型:插入位置为左子树的左结点,进行向右旋转(LL表示的是在做子树的左结点进行插入) 羇袆芁袁薃肇蕿由于在A的左孩子B的左子树上插入结点F,使A的平衡因子由1变为2,成为不平衡的最小二叉树根结点。此时A结点顺时针右旋转,旋转过程中遵循“旋转优先”的规则,A结点替换D结点成为B结点的右子树,D结点成为A结点的左孩子。 蚈莁蚃肆罿虿节(2)RR型 薁膁膆蒇衿肄肆RR型:插入位置为右子树的右孩子,进行向左旋转 羃莆艿聿薂芆芆由于在A的右子树C的右子树插入了结点F,A的平衡因子由-1变为-2,成为不平衡的最小二叉树根结点。此时,A结点逆时针左旋转,遵循“旋转优先”的规则,A结点替换D结点成为C的左子树,D结点成为A的右子树。 薆螆膈莃蒆肇螀(3)LR型 薈莈羁蚆薅羀薀LR型:插入位置为左子树的右孩子,要进行两次旋转,先左旋转,再右旋转;第一次最小不平衡子树的根结点先不动,调整插入结点所在的子树,调整后的树变成LL型树,第二次再调整最小不平衡子树(根据LL型的调整规则,调整为平衡二叉树)。 薈螃螅莇肀莂蚅由于在A的左子树B的右子树上插入了结点F,A的平衡因子由1变为了2,成为不平衡的最小二叉树根结点。第一次旋转A结点不动,先将B的右子树的根结点D向左上旋转提升到B结点的位置,然后再把该D结点向右上旋转提升到A结点的位置。

平衡二叉树的实现及分析

【学生用】 西北农林科技大学信息工程学院《数据结构与C语言综合训练》实习报告 题目:AVL Tree的实现及分析 学号************ 姓名************* 专业班级计算机科学与技术103 指导教师******* 实践日期2011年7月8日-2011年7月18日

目录 一、综合训练目的与要求.................................. 错误!未定义书签。 二、综合训练任务描述 (1) 三、算法设计 (1) 四、详细设计及说明 (11) 五、调试与测试 (11) 六、实习日志 (13) 七、实习总结 (14) 八、附录:核心代码清单 (14)

一、综合训练目的与要求 本综合训练是计算机科学与技术专业重要的实践性环节之一,是在学生学习完《算法分析》课程后进行的综合练习。本课综合训练的目的和任务: 1. 巩固和加深学生对算法分析课程基本知识的理解和掌握; 2. 培养利用算法知识解决实际问题的能力; 3. 掌握利用程序设计语言进行算法程序的开发、调试、测试的能力; 4. 掌握书写算法设计说明文档的能力; 5. 提高综合运用算法、程序设计语言、数据结构知识的能力。 二、综合训练任务描述 1、创建一棵一般二元查找树。 2、判断一般二元查找数是否为AVL树。 3、一般二元查找树转化为AVL。 4、AVL树的插入与删除元素操作。 三、算法设计 (1) 文字描述 首先利用二元查找树的性质创建一棵一般的二元查找树,然后计算每个节点的bf值(平衡因子),通过bf值来判断所建立的二元查找树是否为平衡二叉树,不是的话就把它转换为平衡二叉树。首先把原二元查找树的每个节点的地址存放到一个循环队列中,然后把它们一一插入到建立的平衡二叉树里面,在建立的过程中一是要保证不能插入相同的节点,二是保证插入元素后平衡二叉树还是平衡的,这就要做到边插入边旋转,旋转有四种方式,分别是RR,RL,LR,LL。平衡二叉树的删除操作,首先要找到要删除的节点,要是没有找到的话应该报错,有的话就删除,删除要注意那三种情况,一是所删除节点只有左子树,一是所删除节点只有右子树,然后是所删除节点左右子树都有。 (2)框图

相关文档
相关文档 最新文档