二叉排序树及平衡二叉排序树基本操作实现Word格式文档下载.docx
《二叉排序树及平衡二叉排序树基本操作实现Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《二叉排序树及平衡二叉排序树基本操作实现Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
12
月
27
日
课程设计任务书
2015~2016学年第1学期
学生姓名:
专业班级:
计科二
指导教师:
成俊工作部门:
计算机学院
一、课程设计题目:
二叉排序树与平衡二叉排序树基本操作
二、课程设计内容
用二叉链表作存储结构,编写程序实现二叉排序树上的基本操作:
以回车('
\n'
)为输入结束标志,输入数列L,生成二叉排序树T;
对二叉排序树T作中序遍历;
计算二叉排序树T的平均,输出结果;
输入元素x,查找二叉排序树T,若存在含x的结点,则删除该结点,并作中序遍历;
否则输出信息“无结点x”;
判断二叉排序树T是否为平衡二叉树;
再用数列L,生成平衡二叉排序树BT:
当插入新元素之后,发现当前的二叉排序树BT不是平衡二叉排序树,则立即将它转换成新的平衡二叉排序树BT;
计算平衡的二叉排序树BT的平均查找长度,输出结果。
三、进度安排
1.分析问题,给出数学模型,选择数据结构.
2.设计算法,给出算法描述
3.给出源程序清单
4.编辑、编译、调试源程序
5.撰写课程设计报告
四、基本要求
编写AVL树判别程序,并判别一个二叉排序树是否为AVL树。
二叉排序树用其先序遍历结果表示,如:
5,2,1,3,7,8。
实现AVL树的ADT,包括其上的基本操作:
结点的加入和删除;
另外包括将一般二叉排序树转变为AVL树的操作。
实现提示主要考虑树的旋转操作。
目录
二叉排序树与平衡二叉排序树基本操作1
二、课程设计内容1
三、进度安排1
四、基本要求1
一、概述3
1.课程设计的目的3
2.课程设计的要求3
二、总体方案设计4
三、详细设计6
1.课程设计总体思想6
2.模块划分7
3.流程图8
四、程序的调试与运行结果说明9
五、课程设计总结14
参考文献14
一、概述
1.课程设计的目的
1.充分理解和掌握二叉树、平衡二叉树的相关概念和知识。
2.掌握排序二叉树的生成、结点删除、插入等操作过程。
3.并实现从键盘上输入一系列数据(整型),建立一棵平衡二叉树。
4.任意插入或删除一个结点后判断是否为平衡二叉树。
5.将非平衡二叉树转换成平衡二叉树。
6.按中序遍历输出这棵平衡二叉树。
2.课程设计的要求
计算二叉排序树T的平均查找长度,输出结果;
二、总体方案设计
1)建立二叉排序树,编写二叉排序树T作中序遍历。
2)查找删除二叉排序树函数。
3)编写判断二叉排序树T是否为平衡二叉树函数,把非平衡二叉排序树转换成平衡二叉排序树。
4)编写计算二叉树BT的平均查找长度函数。
我负责的是第一部分,二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
1.若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3.它的左、右子树也分别为二叉排序树。
以链表存储结构创建二叉排序树,以回车('
对二叉排序树T作中序遍历。
中序遍历二叉树算法的框架是:
若二叉树为空,则空操作;
否则
(1)中序遍历左子树(L);
(2)访问根结点(V);
(3)中序遍历右子树(R)。
函数1:
中序遍历二叉树
中序遍历二叉树也采用递归函数的方式,先访问左子树2i,然后访问根结点i,最后访问右子树2i+1.先向左走到底再层层返回,直至所有的结点都被访问完毕。
(谢石林)函数2:
平均查找长度
计算二叉排序树的平均查询长度时,可采用类似中序遍历的递归方式,用s记录总查询长度,j记录每个结点的查询长度,s值初值为0,采用累加的方式最总得到总查询长度s,平均查询长度等于s/i(i为树中结点个数)。
(吴进)函数3:
查找删除二叉排序树函数
输入元素x,查找二叉排序树T,若存在含x的结点,则删该结点,并作中序遍历(执行函数1);
否则输出信息“无x”。
(张常勋)函数4:
判断二叉排序树T是否为平衡二叉树,若不是则用数列L,生成平衡排序二叉树BT;
最后调用函数6
,接着调用函数5.判断二叉排序树是否为平衡二叉树的函数也是采用递归函数的方式,分别判定以树中每个节点为根节点的子树是否为平衡二叉树。
只要有一个子树不为平衡二叉树,则该树便不是平衡二叉树。
函数5:
在平衡二叉树BT上插入新元素,若发现当前的二叉排序树BT不是平衡二叉排序树,则立即将它转
换成新的平衡二叉排序树BT。
三、详细设计
1.课程设计总体思想
1.生成二叉排序树:
建立二叉排序树采用的是边查找边插入的方式。
查找函数采用递归的方式进行查找。
查找是按照二叉排序树的性质进行的,通过比较要插入元素的关键字与当前结点关键字的大小来决定我们是遍历当前结点的哪个子树。
如果小于当前结点关键字,则遍历它的左子树;
大于当前结点关键字,则遍历它的右子树;
等于当前关键字,则此元素不插入原树。
我们按照这样的规律,一直向下遍历,知道它的子树为空,则返回当前结点的上一个结点。
然后利用插入函数将该元素插入原树。
2.中序遍历:
对二叉排序树进行中序遍历采用递归函数的方式。
在根节点不为空的情况下,先访问左子树,在访问根结点,最后访问右子树。
3.平均查找长度:
计算二叉排序树的平均查找长度,仍采用类似中序遍历的递归方式,用s记录总查找长度,j记录每个结点的查找长度,s置初值为0,采用累加的方式最终得到总查找长度s,平均查找长度就等于s/j(i为树中结点的总个数)。
4.删除结点:
删除结点函数,采用边查找变删除的方式。
如果没有查找到,则不对树做任何的修改:
如果查找到结点,则分四种情况分别进行讨论:
(1)该结点左右子树均为空;
(2)该结点仅左子树为空;
(3)该结点仅右子树为空;
(4)该结点左右子树都不为空;
5.用数列L,生成平衡的二叉排序树BT;
当插入新元素之后,发现当前的二叉排序树BT不是平衡二叉排序树,则立即将它转换成新的平衡的二叉排序树BT。
我所负责的模块函数定义如下
voidTraverseOrderDSTable(BSTreeDT,void(*Visit)(ElemType))//按中序遍历
详细的程序代码如下:
typedefstructBSTNode//二叉排序树类型
{ElemTypedata;
structBSTNode*lchild,*rchild;
}BSTNode,*BSTree;
StatusInitDSTable(BSTree&
DT)
{//构造一个空的动态BST查找表DT
DT=NULL;
return1;
}
voidTraverseOrderDSTable(BSTreeDT,void(*Visit)(ElemType))
{//按中序遍历对DT的每个结点调用函数Visit()一次且至多一次
if(DT)
{TraverseOrderDSTable(DT->
lchild,Visit);
Visit(DT->
data);
TraverseOrderDSTable(DT->
rchild,Visit);
}
}
2.模块划分
Main:
主函数模块,在主函数中调用其他函数:
(1)StatusInsertBST(BSTree&
T,ElemTypee)//创建二叉排序树
(2)voidTraverseOrderDSTable(BSTreeDT,void(*Visit)(ElemType))
voidTraverseOrderDSTable(AVLTreeDT,void(*Visit)(ElemType))
//中序遍历二叉排序树和平衡二叉排序树
(3)voidasl()//计算平均长度
(4)BSTreeSearchBST(BSTreeT,KeyTypekey)
voidSearchBST(BSTree&
T,KeyTypekey,BSTreef,BSTree&
p,Status&
flag)
voidDelete(BSTree&
p)
StatusDeleteBST(BSTree&
T,KeyTypekey)//查找并删除结点
(5)StatusInsertAVL(AVLTree&
T,ElemTypee,Status&
taller)
//创建平衡二叉排序树
voidRightBalance(AVLTree&
T)//对以*p为根的二叉排序树作右旋处理,处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点
voidLeftBalance(AVLTree&
T)//对以*p为根的二叉排序树作左旋处理,处理之后p指向新的树根结点,即旋转处理之前的右子树的根结点
AVLTreeSearchAVL(AVLTreeT,KeyTypekey)//衡二叉排序树中进行查找。
3.流程图
四、程序的调试与运行结果说明
主函数代码:
voidmain()
{
intnum,i,select,t,*depth,max,flag;
KeyTypej;
Statusk;
ElemType*r,*tempr,tempbst,tempavl;
BSTreebst,p;
AVLTreeavl,q;
do
{
printf("
请输入要输入的数据的总数,总数要大于0:
"
);
scanf("
%d"
&
num);
if(num<
=0)
printf("
\n输入的总数要大于0,请重新输入:
}
while(num<
=0);
gl_count=num;
r=(ElemType*)malloc(gl_count*(sizeof(ElemType)));
printf("
请输入生成二叉树的整型数据,前后数据用空格隔开:
\n"
for(i=0;
i<
gl_count;
i++)
scanf("
&
r[i].key);
r[i].order=i+1;
\n用户输入的数据