二叉树数据结构课设说明书Word格式文档下载.docx
- 文档编号:22506650
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:33
- 大小:509.46KB
二叉树数据结构课设说明书Word格式文档下载.docx
《二叉树数据结构课设说明书Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《二叉树数据结构课设说明书Word格式文档下载.docx(33页珍藏版)》请在冰豆网上搜索。
//指向该结点左孩子结点的指针
structtree*rchild;
//指向该结点右孩子结点的指针
};
2.各模块的伪码算法
计算树的高度
intCountHigh(structtree*T)
{intlhigh=0;
//存储以T指向的结点为根结点的左子树的高度
intrhigh=0;
//存储以T指向的结点为根结点的右子树的高度
if(T->
lchild==NULL&
&
T->
rchild==NULL)//若该子树就一个根结点
returnT->
level;
else{if(T->
lchild!
=NULL)//若该子树有左子树
lhigh=CountHigh(T->
lchild);
//计算左子树高度
rchild!
=NULL)//若该子树有右子树
rhigh=CountHigh(T->
rchild);
//计算右子树高度
if(lhigh>
rhigh)//返回左右子树高度最大值
returnlhigh;
elsereturnrhigh;
}}
2.计算分支结点数
intCountNleaf(structtree*T)
{intlnleaf=0;
//存储左子树分支结点数
intrnleaf=0;
//存储右子树分支结点数
if(T->
return0;
else{if(T->
=NULL)//若有左子树
lnleaf=CountNleaf(T->
//计算左子树分支结点数
if(T->
=NULL)//若有右子树
rnleaf=CountNleaf(T->
//计算右子树分支结点数
return(1+lnleaf+rnleaf);
//返回分支结点数}}
3计算叶子节点数
intCountLeaf(structtree*T){
intlleaf=0;
//存储左子树叶子结点数
intrleaf=0;
//存储右子树叶子结点数
return1;
else{if(T->
lleaf=CountLeaf(T->
//计算左子树叶子结点数
rleaf=CountLeaf(T->
//计算右子树叶子结点数
return(lleaf+rleaf);
//返回左右子树叶子结点数总和}}
4.在确定位置增加一个新的叶子结点
voidAddPoint(structtree*T){intgoal;
//存储新叶子结点元素
intpgoal;
//存储新叶子结点的父结点元素intwhether;
//判断插入结果
printf("
请输入新结点的数据元素:
"
);
scanf("
%d"
&
goal);
请输入新结点的父结点中的数据元素:
scanf("
pgoal);
whether=Add(T,pgoal,goal);
//递归查找父结点并进行插入操作
switch(whether)//判断插入结果
{case-1:
printf("
无法插入结点,因为父结点已有两个孩子结点!
\n"
break;
case0:
无法插入该结点,因为树中不存在输入的父结点!
case1:
{printf("
结点插入成功!
PrintTree(T);
}break;
default:
}}
5.递归查找确定的叶子结点并删除
intDelete(structtree**T,intgoal){intwhether;
if((*T)->
data==goal)//若该结点就为要删除的结点
{if((*T)->
(*T)->
rchild==NULL)//若该结点为叶子结点
{free(*T);
*T=NULL;
return1;
}
else//若该结点不是叶子结点{return-1;
else//若该结点不是要删除的结点
return0;
else//若该结点不是叶子结点{if((*T)->
{whether=Delete(&
((*T)->
lchild),goal);
//在其左子树中查找要删除的结点
if(whether==0&
=NULL)//若左子树中没找到要删除的结点且存在右子树
returnDelete(&
rchild),goal);
//在其右子树中查找要删除的结点
else//若右子树不存在returnwhether;
else//若左子树不存在
//在其右子树中查找要删除的结点}}}
6.递归交换左右子树
voidExchange(structtree*T){structtree*changePtr;
if(T!
=NULL)//若该根结点存在{changePtr=T->
lchild;
T->
lchild=T->
rchild;
rchild=changePtr;
//交换该根结点的左右子树
Exchange(T->
//对其左子树进行所有左右子树交换
//对其右子树进行所有左右子树交换}}
7.层序遍历该树
voidLevelTravel(structtree*T){inti;
structtree*t[100];
//将树的每个结点按一定编号存储到一维数组中
层序遍历为:
for(i=0;
i<
100;
i++)t[i]=NULL;
if(T!
=NULL)
t[1]=T;
//根结点编号下标为1
for(i=1;
i++)if(t[i]!
{if(t[i]->
t[2*i]=t[i]->
//存储左子树根结点
if(t[i]->
t[2*i+1]=t[i]->
//存储右子树根结点
%-3d"
t[i]->
data);
//按数组顺序打印出各结点元素}printf("
}
8.先序遍历
voidPreTravel(structtree*T){if(T!
=NULL)//若根结点存在
{printf("
T->
//打印根结点元素
PreTravel(T->
//遍历左子树PreTravel(T->
//遍历右子树}}
9.中序遍历
voidMidTravel(structtree*T){if(T!
{MidTravel(T->
//遍历左子树
//打印根结点元MidTravel(T->
//遍历右子树}}
10.后序遍历
voidAfterTravel(structtree*T){if(T!
{AfterTravel(T->
AfterTravel(T->
//遍历右子树printf("
//打印根结点元素}
3.函数的调用关系图
4.调试分析
a、调试中遇到的问题及对问题的解决方法
1、输出的运行界面不整齐,例如“*”在编写程序的时候输入不整齐,运行出来的界面就不好看。
2、在使用解释符号时应该注意“//”,不适合于TC的环境,要用“/**/”。
3、函数的调用不正确。
解决方法:
当在一个函数中要调用另一个函数时,必须在调用函数的函数块中对被调用函数进行类型的声明
b、算法的时间复杂度和空间复杂度
时间复杂度:
T(n)=O(n);
空间复杂度:
S(n)=O(f(n));
5.测试结果
1.创建二叉树
2.计算二叉树的高度,分支节点数以及叶子节点数
3.在指定位置插入数据元素
4.删除指定位置数据元素
5.交换左右子树
6.层序遍历
7.先序遍历
8.中序遍历
9.后序遍历
10.结束
6.源程序(带注释)
#include<
stdio.h>
stdlib.h>
//将树的结点定义为结构
structtree{intdata;
intlevel;
structtree*lchild;
structtree*rchild;
//指向该结点右孩子结点的指针}
intpretotal=0;
//遍历先序序列的下标
structtree*GetSequence();
//读取先序序列和中序序列
structtree*CreateTree(intstart,intend,inttotal,intpredata[],
intmiddata[]);
//创建树
intFindElem(intmiddata[],intgoaldata,inttotal);
//查找goaldata在middat中的下标
intGetChoose();
//读取用户选择的操作
voidCountTree(structtree*T);
//对树进行计算操作
intCountHigh(structtree*T);
//计算树的高度
intCountNleaf(structtree*T);
//计算树的分支结点数
intCountLeaf(structtree*T);
//计算树的叶子结点数
voidPointTree(structtree*T);
//增加或删除叶子结点
voidAddPoint(structtree*T);
//增加叶子结点
intAdd(structtree*T,intpgoal,intgoal);
//递归查找叶子结点增加的位置
voidDeletePoint(structtree*T);
//删除叶子结点
intDelete(structtree**T,intgoal);
//递归查找叶子结点删除的位置
voidExchangeTree(structtree*T);
//交换所有结点的左右子树
voidExchange(structtree*T);
//递归调换所有结点的左右子树
voidTravelTree(structtree*T);
//遍历树
voidLevelTravel(structtree*T);
//层序遍历该树
voidPreTravel(structtree*T);
//先序遍历该树
voidMidTravel(structtree*T);
//中序遍历该树
voidAfterTravel(structtree*T);
//后序遍历该树
voidPrintTree(structtree*T);
//按二叉树的格式打印该树
intf(intn);
//计算2的n次方
voidFreeTree(structtree*T);
//程序结束后释放动态生成的结点
main(){intchoose=-1;
//存储用户选择操作的序号
structtree*headPtr=NULL;
//指向树根结点的指针
headPtr=GetSequence();
//通过先序序列和中序序列建立一棵二叉树并用headPtr指向该树的根结点
PrintTree(headPtr);
//按树的格式打印该二叉树
while(choose){choose=GetChoose();
//由用户输入选择操作的序号
switch(choose){case1:
CountTree(headPtr);
//计算二叉树高度、分支结点数及叶子结点数
case2:
PointTree(headPtr);
case3:
ExchangeTree(headPtr);
//所有结点左右子树交换
case4:
TravelTree(headPtr);
//遍历default:
system("
CLS"
谢谢使用!
再见!
!
FreeTree(headPtr);
//释放动态申请的结点system("
pause"
/*函数功能:
读取输入的树的先序序列和中序序列,传递参数:
无,返回值:
指向由先序序列和中序序列确定的二叉树的根结点指针*/
structtree*GetSequence(){intt1=0;
//统计先序序列元素个数
intt2=0;
//统计中序序列元素个数inttotal;
//统计树结点个数
intmid;
//存储先序序列第一个元素在中序序列中的下标
intwhether=1;
//判断是否存在该树charch;
//判断序列结束符
intpredata[100];
//存储先序序列intmiddata[100];
//存储中序序列
structtree*headPtr;
//指向由先序序列和中序序列确定的二叉树的根结点
while(whether)
************二叉树操作**************\n”);
\n\n"
请输入先序序列(不同结点数据用“空格”隔开,以“回车”作为序列结束符):
ch='
'
;
while(ch!
='
\n'
)//读取先序序列{scanf("
predata[t1]);
t1++;
ch=getchar();
}printf("
请输入中序序列(不同结点数据用“空格”隔开,以“回车”作为序列结束符):
)//读取中序序列{scanf("
middata[t2]);
t2++;
}if(t1==t2)//若先序序列中序序列元素个数相等
{total=t1;
whether=0;
elseprintf("
两个序列结点个数不同,不能构成树,请重新输入!
!
****************************************\n"
headPtr=malloc(sizeof(structtree));
//动态生成根结点
headPtr->
data=predata[0];
headPtr->
lchild=NULL;
rchild=NULL;
mid=FindElem(middata,predata[pretotal],total);
//查找根结点元素在中序序列中的下标
pretotal++;
//遍历先序序列
lchild=CreateTree(0,mid-1,total,predata,middata);
//创建根结点的左子树
rchild=CreateTree(mid+1,total-1,total,predata,middata);
//创建根结点的右子树
returnheadPtr;
//返回根结点指针}
根据先序序列和中序序列递归建立每棵子树,传递参数:
中序序列起始下标start,终止下标end,结点总个数total,先序序列predata,中序序列middata,返回值:
根结点指针*/
structtree*CreateTree(intstart,intend,inttotal,intpredata[],intmiddata[])
{intmid;
structtree*T;
if(start<
=end)//若存在该子树
{T=malloc(sizeof(structtree));
//生成该子树的根结点
data=predata[pretotal];
T->
//查找该子树根结点在中序序列中的下标
lchild=CreateTree(start,mid-1,total,predata,middata);
//创建该子树的左子树
rchild=CreateTree(mid+1,end,total,predata,middata);
//创建该子树的右子树
returnT;
//返回根结点指针}else//若不存在该子树returnNULL;
查找确定元素在中序序列中的下标,传递参数:
中序序列middata,确定元素goaldata,结点总个数total,返回值:
该确定元素在中序序列中的下标*/
intFindElem(intmiddata[],intgoaldata,inttotal)
{inti=0;
while(middata[i]!
=goaldata)
i++;
returni;
读取用户输入的操作序号,传递参数:
用户输入的操作序号*/
intGetChoose(){intchoose;
*********************************************\n"
您可以选择进行的操作:
1、计算(二叉树的高度、分支结点数以及叶子结点数);
2、增删结点操作;
3、交换左右子树操作;
4、遍历操作\n"
0、退出\n"
请输入要进行操作的序号:
choose);
while(!
(choose>
=0&
choose<
=4))
输入无效!
请重新输入:
returnchoose;
计算树的相关信息(包括树的高度、分支结点数、叶子结点数),传递参数:
指向根结点的指针,返回值:
无*/
voidCountTree(structtree*T){inthigh=0;
//存储树的高度
intnleaf=0;
//存储分支结点数intleaf=0;
//存储叶子结点数
high=CountHigh(T);
nleaf=CountNleaf(T);
//计算分支结点数
leaf=CountLeaf(T);
//计算叶子结点数
\n******************************************\n"
树的高度为:
%d\n"
high);
分支结点数为:
nleaf);
叶子结点数为:
leaf);
******************************************\n\n"
计算树的高度,传递参数:
根结点指针,返回值:
以T指向的结点为根结点的子树的高度*/
{intlhigh=0;
rchild==NULL)//就一个根结点
returnT->
lhigh=CountHigh(T->
rhigh=CountHigh(T->
rchil
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 数据结构 说明书