广工数据结构实验报告平衡二叉树.docx

上传人:b****8 文档编号:9158877 上传时间:2023-02-03 格式:DOCX 页数:20 大小:74.30KB
下载 相关 举报
广工数据结构实验报告平衡二叉树.docx_第1页
第1页 / 共20页
广工数据结构实验报告平衡二叉树.docx_第2页
第2页 / 共20页
广工数据结构实验报告平衡二叉树.docx_第3页
第3页 / 共20页
广工数据结构实验报告平衡二叉树.docx_第4页
第4页 / 共20页
广工数据结构实验报告平衡二叉树.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

广工数据结构实验报告平衡二叉树.docx

《广工数据结构实验报告平衡二叉树.docx》由会员分享,可在线阅读,更多相关《广工数据结构实验报告平衡二叉树.docx(20页珍藏版)》请在冰豆网上搜索。

广工数据结构实验报告平衡二叉树.docx

广工数据结构实验报告平衡二叉树

数据结构设计性实验报告

课程名称数据结构实验■

题目名称平衡二叉树

学生学院_计算机学院

专业班级_

学号

学生姓名

指导教师

2015年6月14日

一、设计任务、要求以及所用环境及工具.4

实验设计任务.4

实验要求.4

编程环境.4

抽象数据类型及接口简要描述.5

抽象数据类型.5

接口简要描述.7

算法设计8

程序测试17

测试代码.17

测试结果.18

测试分析.20

思考与小结21

设计任务、要求以及所用环境及工具

实验设计任务

以教材中讨论的各种抽象数据类型为对象,利用C语言的数据类型表示和实现其中某个

抽象数据类型。

可选的抽象数据类型如下表所列:

编号

抽象数据类型

基本难度

存储结构

1

栈和队列

1.0

顺序和链接

2

线性表

1.0

顺序和链接

3

哈希表

1.1

任选

4

二叉树

1.2

任选

5

1.2

任选

6

二叉排序树

1.2

任选

7

平衡二叉树

1.3

任选

8

1.2

任选

9

并查集

1.2

任选

10

B树

1.4

任选

11

有向图

1.3

任选

12

无向图

1.3

任选

13

有向带权图

1.3

任选

注:

如果基本操作数量较多,可选择实现其中一个基本操作子集。

实验要求

实验要求如下:

1•首先了解设计的任务,然后根据自己的基础和能力从中选择一题。

一般来说,选择题目应以在规定的时间内能完成,并能得到应有的锻炼为原则。

若学生对教材以外的相关

题目较感兴趣,希望选作实验的题目时,应征得指导教师的认可,并写出明确的抽象数据类

型定义及说明。

2.实验前要作好充分准备,包括:

理解实验要求,掌握辅助工具的使用,了解该抽象数据类型的定义及意义,以及其基本操作的算法并设计合理的存储结构。

3.实验时严肃认真,要严格按照要求独立进行设计,不能随意更改。

注意观察并记录各种错误现象,纠正错误,使程序满足预定的要求,实验记录应作为实验报告的一部分。

4.实验后要及时总结,写出实验报告,并附所打印的问题解答、程序清单,所输入的数据及相应的运行结果。

编程环境

下完成。

本次实验设计采用C++语言,在MicrosoftVisualStudio2010IDE

所创建的项目类型Win32控制台应用程序:

rl:

tzd

HET募権怪4.*

J□

"三耙■耐3EP|

C*<

底总¥i4C4+

ATk

ViitadC--4

CLU

mi*

ECiy.i

G91D.

EiW

•L

a话亦需

Z••穷A

 

抽象数据类型及接口简要描述

本次数据结构实验设计我选择的是二叉平衡树(AVL),使用C++面向对象编程语言实现。

利用C++泛型编程技术完成AVL类AVLTree。

抽象数据类型

1.平衡二叉树结点的ADT为:

template

classAVLTreeNode

{

public:

T_key;II结点关键字

int_bf;II结点平衡因子

AVLTreeNode*_lchild;II结点的左孩指针

AVLTreeNode*_rchild;II结点的右孩指针

II构造函数

boolbf)

AVLTreeNode(Tkey‘AVLTreeNode*lchild,AVLTreeNode*rchild:

_key(key),_lchild(lchild),_rchild(rchild),_bf(bf){};

};

2.平衡二叉树类AVLTree的定义为:

templateclassAVLTree

{

private:

AVLTreeNode*_Root;//树的根结点bool_taller;//树是否长高的标记

public:

AVLTree(){_Root=NULL;};//默认构造函数

~AVLTree(){};//析构函数

private:

II删除时的左平衡操作

voiddelLeftBalance(AVLTreeNode*&tree,intchildBf);

II删除时的右平衡操作

voiddelRightBalance(AVLTreeNode*&tree,intchildBf);II中序遍历

voidinOrder(AVLTreeNode*&tree);

II前序遍历voidpreOrder(AVLTreeNode*&tree);

II后序遍历voidpostOrder(AVLTreeNode*&tree);

II像二叉树中插入新结点

boolinsert(AVLTreeNode*&tree,Tkey,bool&taller);

II插入时导致LL型失衡的右旋操作

voidrightRotate(AVLTreeNode*&tree);

II插入时导致RF型失衡的左旋左旋

voidleftRotate(AVLTreeNode*&tree);

II左平衡处理

voidleftBalance(AVLTreeNode*&tree);

II右平衡处理

voidrightBalance(AVLTreeNode*&tree);

II删除时的左平衡处理

voiddLeftBalance(AVLTreeNode*&tree);

//删除时的右平衡处理

voiddRightBalance(AVLTreeNode*&tree);

//打印二叉树

voidprint(AVLTreeNode*&tree);

//查找二叉树中指定结点

AVLTreeNode*search(AVLTreeNode*&tree,Tkey);

//查找二叉树最小的结点

AVLTreeNode*minimumNode(AVLTreeNode*&tree);

//查找二叉树最大的结点

AVLTreeNode*maxmumNode(AVLTreeNode*&tree);

//删除指定关键字的结点

AVLTreeNode*remove(AVLTreeNode*&tree,AVLTreeNode*z);

//销毁二叉树,释放所有申请的空间

voiddestory(AVLTreeNode*&tree);

};

接口简要描述

3.遍历操作接口

遍历二叉树是指从根结点出发,按照某种次序访问二叉树所有结点,使得每个结点

被且仅被访问一次,这里的访问可以是输出、比较、更新、查看结点信息等各种操作。

遍历是二叉树的一类重要操作,也是二叉树的其他一些操作和各种应用算法的基本框架。

用V表示根节点,用L表示左孩子,用R表示右孩子,且规定先L后R的访问顺序,则有VLR(前序)、LVR(中序)、LRV(后续)三种遍历算法。

对于图a中的二叉树,其遍

历结果为:

S3

479S'

1955

(50)

前序遍历:

884719555098

中序遍历:

194750558898后序遍历:

195055479888

AVLTree类提供了三个遍历接口,分别是前序、中序、后续遍历。

这三个接口都使用递归算法实现,调用遍历接口可以得到相应遍历次序的序列。

4.插入接口

插入操作是AVL树的关键操作,用于向AVL插入新的结点,其难点在于每次插入操作都要维护树的平衡性。

向平衡二叉树中插入一个新结点后如果破坏了平衡二叉树的平衡性,首先要找出插入新结点后失去平衡的最小子树(最小失衡子树)根结点的指针,然后再调整这个子树中有关结点之间的连接关系,使之成为新的平衡二叉树。

当进行插入操作时,找到该需要插入结点的位置插入后,从该结点起向上寻找,第一个不平衡的结点(平衡因子变成了-2或2)。

以该结点为根的子树即为最小失衡子树。

二叉排序树转成平衡二叉树失去平衡后进行调整的四种情况:

(1)单向右旋平衡处理。

当在左子树插入左结点,使平衡因子由1增至2时。

(2)单向左旋平衡处理。

当在右子树中插入有节点,使平衡因子由-1增至-2时。

(3)双向旋转(先左后右)平衡处理。

当在左子树上插入右结点,使平衡因子由1增至2时。

(4)双向旋转(先右后左)平衡处理。

当在右子树上插入左结点,使平衡因子由-1增至-2时。

插入接口对上述的情况做了处理。

5.删除接口

删除操作与插入操作一样,需要在每次删除时维护树的平衡性,而且删除比插入需要处理的情况更加复杂。

在实验过程中我主要想法是抓住“判断树的高度是否降低,若是则进行平衡因子判断及结点调整”。

总的来说,导致树高度降低的原因就是某个结点的平衡因子由1(或-1)变成0的时候。

删除操作采用递归算法实现。

6.二叉树查找接口

AVLTree类供提供了三种查找操作,一种是传统意义上的查找某个指定关键字的结点,另外两个是查找关键字最小及最大结点。

查找算法使用递归实现。

7.打印二叉树接口

二叉树打印即描述二叉树的结构构成情况,例如描述某个结点的左孩子及右孩子指针指向,依据该接口的输出语句可描画出二叉树的结构。

打印接口同样采用递归算法来实现。

8.销毁二叉树接口

该接口将创建AVL树时申请的结点资源释放,使用递归算法将整棵二叉树进行销毁。

算法设计

1.孩子表示法存储结构

//定义并初始化一个新结点

//AVLTreeNode类的默认构造函数

AVLTreeNode(Tkey,AVLTreeNode*lchild,AVLTreeNode*rchild,boolbf):

_key(key),_lchild(lchild),_rchild(rchild),_bf(bf){};

2.//前序遍历

//接口

template

voidAVLTree:

:

preOrder()

{

preOrder(_Root);

}

//类的私有函数,供接口调用template

voidAVLTree:

:

preOrder(AVLTreeNode*&tree)

{

if(tree)

{

cout<_key<<"";preOrder(tree->_lchild);preOrder(tree->_rchild);

}

}

3.//中序遍历templatevoidAVLTree:

:

inOrder(){

inOrder(_Root);

}templatevoidAVLTree:

:

inOrder(AVLTreeNode*&tree){

if(tree)

{inOrder(tree->_lchild);cout<_key<<"";inOrder(tree->_rchild);

}

}

4.//后序遍历

//后序遍历templatevoidAVLTree:

:

postOrder(){

postOrder(_Root);

template

voidAVLTree:

:

postOrder(AVLTreeNode*&tree)

{

if(tree)

{postOrder(tree->_lchild);postOrder(tree->_rchild);cout<_key<<"";

}

}

5.//查找指定结点template

AVLTreeNode*AVLTree:

:

search(AVLTreeNode*&tree,Tkey)

{

AVLTreeNode*temp=tree;

while(temp!

=NULL)

{

if(temp->_key==key)returntemp;

elseif(temp->_key>key)temp=temp->_lchild;

else

temp=temp->_rchild;

}

returnNULL;

}

6.//查找最小结点template

AVLTreeNode*AVLTree:

:

minimumNode()

{

returnminimumNode(_Root);

}

template

AVLTreeNode*AVLTree:

:

minimumNode(AVLTreeNode*&tree)

{

AVLTreeNode*temp=tree;

while(temp->_lchild)

{

temp=temp->_lchild;

}

returntemp;

7.//查找最大结点templateAVLTreeNode*AVLTree:

:

maxmumNode(){

returnmaxmumNode(_Root);

}

template

AVLTreeNode*AVLTree:

:

maxmumNode(AVLTreeNode*&tree)

{

AVLTreeNode*temp=tree;

while(temp->_rchild)

{

temp=temp->_rchild;

}

returntemp;

}

8.//打印二叉树templatevoidAVLTree:

:

print(){

print(_Root);

}

template

voidAVLTree:

:

print(AVLTreeNode*&tree)

{

if(tree)//如果tree不为空

{

if(tree->_lchild)//结点有左孩子

cout<<"节点"<_key<<"有左孩子为"<_lchild->_key<

if(tree->_rchild)

cout<<"节点"<_key<<"有右孩子为"<_rchild->_key<

print(tree->_lchild);print(tree->_rchild);

}

}

9.//销毁二叉树templatevoidAVLTree:

:

destory()

{

destory(_Root);

}

template

voidAVLTree:

:

destory(AVLTreeNode*&tree)

{

if(tree->_lchild!

=NULL)destory(tree->_lchild);

if(tree->_rchild!

=NULL)destory(tree->_rchild);

if(tree->_lchild==NULL&&tree->_rchild==NULL)

{

delete(tree);

tree=NULL;

}

}

10.//插入函数templateboolAVLTree:

:

insert(Tkey)

{

_taller=false;returninsert(_Root,key,_taller);

}templateboolAVLTree:

:

insert(AVLTreeNode*&tree,Te,bool&taller){

if(!

tree)

{

tree=newAVLTreeNode(e,NULL,NULL,0);

tree->_bf=EH;

tree->_lchild=tree->_rchild=NULL;taller=true;

}

else

{

if(e==tree->_key)//如果e已经存在

{

taller=false;//则树不长高

returnfalse;

}

if(e_key)

{

if(!

insert(tree->_lchild,e,taller))returnfalse;

if(taller)

switch(tree->_bf)

{

caseLH:

leftBalance(tree);taller=false;break;

caseRH:

rightBalance(tree);taller=false;break;

caseEH:

tree->_bf=LH;taller=true;break;

}

}

}

else

{

if(!

insert(tree->_rchild,e,taller))returnfalse;

if(taller)

{

switch(tree->_bf)

{

caseLH:

tree->_bf=EH;taller=false;break;

caseRH:

rightBalance(tree);taller=false;break;

caseEH:

tree->_bf=RH;taller=true;break;

}

}

11.//左旋函数

template

voidAVLTree:

:

leftRotate(AVLTreeNode*&tree)

{

AVLTreeNode*R=tree->_rchild;tree->_rchild=R->_lchild;

R->_lchild=tree;tree=R;

}

12.//右旋函数

template

voidAVLTree:

:

rightRotate(AVLTreeNode*&tree)

{

AVLTreeNode*L=tree->_lchild;tree->_lchild=L->_rchild;

L->_rchild=tree;

tree=L;

}

13.//左平衡处理

template

voidAVLTree:

:

leftBalance(AVLTreeNode*&tree)

{

AVLTreeNode*Lr;L=tree->_lchild;switch(L->_bf){caseLH:

AVLTreeNode*L;

//L指向tree的左孩子

//检查左孩子的平衡度,并做相应的处理

//新结点插入在左子树的左孩子上,需要做单右旋处理

tree->_bf=L->_bf=EH;rightRotate(tree);break;

caseRH:

//新结点插入在左子树的右孩子上,需要做先左后右旋转处理

Lr=L->_rchild;switch(Lr->_bf){

caseLH:

L->_bf=EH;tree->_bf=RH;break;

caseRH:

tree->_bf=EH;L->_bf=LH;break;

caseEH:

tree->_bf=L->_bf=EH;break;

}Lr->_bf=EH;leftRotate(tree->_lchild);rightRotate(tree);

}

}

14.//右平衡处理templatevoidAVLTree:

:

rightBalance(AVLTreeNode*&tree){

AVLTreeNode*R;AVLTreeNode*Rl;

R=tree->_rchild;switch(R->_bf)

{

caseRH:

//新结点插入到右子树的右结点上,单纯做左旋处理。

tree->_bf=EH;

R->_bf=EH;leftRotate(tree);break;

caseEH:

tree->_bf=RH;R->_bf=LH;leftRotate(tree);break;

caseLH:

//新结点插入到右子树的左结点上,做先右后左处理。

Rl=R->_lchild;

switch(Rl->_bf)

{

caseLH:

tree->_bf=EH;R->_bf=LH;break;

caseEH:

tree->_bf=R->_bf=EH;break;

caseRH:

tree->_bf=EH;R->_bf=RH;

break;

}

Rl->_bf=EH;rightRotate(tree->_rchild);leftRotate(tree);

}

}

15.//删除结点时左平衡操作templatevoidAVLTree:

:

delLeftBalance(AVLTreeNode*&tree,intchildBf){

if(tree->_lchild==NULL||childBf!

=EH&&tree->_lchild->_bf==EH)

{

switch(tree->_bf)

{

caseLH:

tree->_bf=EH;break;

caseRH:

rightBalance(tree);break;

caseEH:

tree->_bf=RH;break;

}

}

}

16.//删除结点时的右平衡操作template

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1