二叉树共同祖先求解课设报告.docx
- 文档编号:24454114
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:18
- 大小:232.45KB
二叉树共同祖先求解课设报告.docx
《二叉树共同祖先求解课设报告.docx》由会员分享,可在线阅读,更多相关《二叉树共同祖先求解课设报告.docx(18页珍藏版)》请在冰豆网上搜索。
二叉树共同祖先求解课设报告
沈阳航空航天大学
课程设计报告
课程设计名称:
数据结构课程设计
课程设计题目:
二叉树中两结点共同祖先求解
院(系):
计算机学院
专业:
计算机科学与技术
目录
1课程设计介绍1
1.1课程设计内容1
1.2课程设计要求1
2课程设计原理2
2.1课设题目粗略分析2
2.2原理图介绍2
2.2.1功能模块图3
2.2.2流程图分析4
3数据结构分析8
3.1存储结构8
3.2算法描述8
4调试与分析10
4.1调试过程10
4.2程序执行过程10
参考文献12
附录(关键部分程序清单)13
1课程设计介绍
此章介绍了本程序的设计内容及要求,本程序利用了栈对二叉树中两结点的共同祖先的求解问题进行了系统化。
1.1课程设计内容
结点的祖先是指从根结点到所查找结点经过的不包括自身在内的结点。
假设二叉树采用二叉链的结构存储,建立一棵树,然后输入两个值,判断是否在树中存在,若存在则求解这两个值的共同祖先并输出。
1.2课程设计要求
(1)利用所学知识,设计相应的数据结构;
(2)熟练运用开发环境;
(3)完成软件的设计与编码;
(4)熟练掌握基本的调试方法;
(5)提交符合课程设计规范的报告。
2课程设计原理
此章介绍了本程序的设计原理,对课设题目进行了分析,并对流程图进行了分析介绍。
2.1课设题目粗略分析
根据课设题目要求,拟将整体程序分为三大模块。
此三个模块相互独立,没有嵌套调用的情况,以下是三个模块的大体分析:
(通过实例讲解写算法的思路,运行过程)
(1)二叉树的创建模块。
此模块通过输入二叉树的先序遍历序列创建二叉链表表示的二叉树,输入时以空格键表示空结点。
(2)分别查找祖先模块。
此模块用两个栈分别存储输入的两个结点的祖先,通过循环判断,对二叉树的结点进行压栈与出栈操作,最后将从根结点到所输结点经过的结点(即结点的祖先)存入栈中。
(3)共同祖先查找模块。
此模块通过比较两个栈中元素,找到所输入的两结点的共同祖先,并执行出栈操作,以实现对两结点共同祖先的查找。
2.2原理图介绍
此部分主要分为功能模块图和流程图分析两部分。
功能模块图将各模块的简单关系表示出来,而流程图则将模块内的执行过程表示出来,更为详尽。
2.2.1功能模块图
图2.1功能模块图
功能模块图如图2.1所示。
本程序主要分为三大模块:
创建二叉树模块,查找祖先模块,查找共同祖先模块。
这三个模块是独立的,不互相调用。
查找共同祖先模块在查找过程中需要用到查找结点祖先模块得到的栈,通过比较存有两个结点祖先的栈中数据,找到两结点共同祖先。
(1)二叉树的创建模块。
此模块通过输入二叉树的先序遍历序列创建二叉链表表示的二叉树,输入时以空格键表示空结点。
(2)分别查找祖先模块。
此模块用两个栈分别存储输入的两个结点的祖先,通过循环判断,对二叉树的结点进行压栈与出栈操作,最后将从根结点到所输结点经过的结点(即结点的祖先)存入栈中。
(3)共同祖先查找模块。
此模块通过比较两个栈中元素,找到所输入的两结点的共同祖先,并执行出栈操作,以实现对两结点共同祖先的查找。
2.2.2流程图分析
(1)主函数流程图如图2.2所示。
图2.2主函数流程图
主函数通过调用子函数实现程序整体的执行。
首先调用creatree()函数创建一棵二叉链式存储结构的二叉树,然后调用preorder()函数遍历二叉树,再调用find()函数分别查找所输入两结点的祖先,。
当x或y值为-1时,所输入结点在创建的二叉树中不存在;祖先是指从根结点到所查找结点经过的不包括自身在内的结点,因此,当所输结点值与根结点值相等时,找不到输入的两结点的共同祖先;其他情况下,通过调用Ancestor()函数可以输出共同祖先。
(2)先序遍历创建二叉树的流程图如图2.3所示。
图2.3先序遍历创建二叉树流程图
此函数的作用是读取所输入的二叉树的先序遍历序列,建立一棵二叉树,若输入空格则该结点为空。
对此函数创建的二叉树,再通过preorder()函数先序遍历并输出先序遍历序列。
(3)查找单个结点祖先的流程图如图2.4所示。
图2.4查找单个结点祖先函数流程图
此函数通过标记数组辅助进行判断,将结点的祖先入栈。
若结点有左孩子,则标记为0,循环判断,到左侧分支的最后一个结点时,标记为1。
最后,找不到结点或结点祖先时,将x返回-1;当树中结点与所输入的结点相等时,将x返回栈顶位置数值。
(4)查找两结点共同祖先的流程图如图2.5所示。
图2.5查找共同祖先函数流程图
此函数中,栈sq和sp分别储存所输入的两结点的祖先。
只有在树的同一层才可能找到两结点的共同祖先,因此,在栈的top指针位置相同时,比较两个栈中数据,在相等时,将数据出栈,即为两结点共同祖先。
3数据结构分析
此章介绍了本程序所用的数据结构,对所用的存储结构进行了分析,并对算法进行了详细的描述。
3.1存储结构
定义二叉树的二叉链表存储结构,包含3个域:
数据域和左右指针域,数据域储存结点数值,左右指针域分别存储该结点的左右孩子。
结构体之间用指针连起来,动态建立二叉链表,建立一棵二叉树。
typedefstructnode
{
chardata;
structnode*lchild,*rchild;
}treenode,*bintree;
定义一个栈的存储结构,查找结点祖先时,将二叉树结点的祖先入栈,查找共同祖先时,将两个栈中数据比较,共同祖先进行出栈操作。
typedefstructstack
{
bintreedata[MAXSIZE];//MAXSIZE定义为100
inttag[MAXSIZE];//tag[]为标记数组
inttop;//top为栈的长度
}seqstack;
3.2算法描述
对于二叉树中两结点共同祖先的查找,首先先序遍历创建二叉树,然后分别查找输入的两结点的祖先并存入栈中,通过比较两个栈中数据,找到两结点共同祖先并出栈,即实现了二叉树中两结点共同祖先的查找。
(参考书上算法描述)
(1)先序遍历创建二叉树,简单算法描述如下:
首先进入creatree()函数,输入二叉树先序遍历序列,结点为空时输入空格。
读入先序序列,若为空格,则该结点为空,否则,为此结点申请空间并创建此结点,这样递归就动态建立了一棵二叉链结构存储的二叉树。
(2)查找单个结点祖先,简单算法描述如下:
进入find()函数。
首先,令栈空。
当二叉树中结点不为空或栈不为空时,判断二叉树中结点是否为空,分为两种情况:
a)若p指向的结点不为空,则将栈顶位置在标记数组中标记为0,将p指向的结点入栈,并令p指向入栈结点的左孩子;
b)若p指向的结点为空,则在栈不为空且栈顶的下一个位置在标记数组中不为0时,将p指向的结点出栈,当p指向的结点不为空和该结点值与输入的结点的值相等能同时满足时,x返回栈顶位置数值,即栈中祖先数目,跳出循环,结束对单个结点祖先的查找,当以上两条件不能同时满足时,令p为空;在栈不为空且栈顶的下一个位置在标记数组中不为0这两个条件不能同时满足时,将栈顶的下一个位置地址赋给p,并将栈顶的下一个位置在标记数组中标记为1,令p指向右孩子。
当二叉树中结点不为空或栈不为空不能满足时,即找不到结点或结点祖先时,x返回-1。
(3)查找两结点共同祖先,简单算法描述如下:
进入Ancestor()函数,sq与sp栈分别存储所输入两结点的祖先。
当sq与sp的栈顶位置不相等时,若sq栈中数据数目大于sp时,将sq中栈顶元素出栈,否则,将sp中栈顶元素出栈。
在sq与sp的栈顶位置相等条件下,当sp栈不为空(或sq栈不为空)时,若sq栈顶元素与sp栈顶元素数值相等,则将此数值输出,并将此元素从sq和sp中出栈。
4调试与分析
此章介绍了本程序调试过程中遇到的问题及解决方法,并以实例对程序执行过程进行了讲解。
4.1调试过程
在调试程序过程中主要遇到以下几类问题:
(1)一些基本语法错误;(具体)
解决方法:
通过跟踪调试慢慢改正。
(2)主函数不完善,当输入结点在二叉树中不存在时,输出的共同祖先无显示;
分析:
在find()函数中,当在二叉树中找不到与输入结点相等的结点时,令x返回-1。
因此,当输入结点在二叉树中不存在时,应满足x或y值为-1。
解决方法:
在主函数中添加if判断语句,当x或y值为-1时,输出“输入结点不存在”。
(3)当输入结点中有根结点时,输出的共同祖先无显示;
分析:
结点的祖先是指从根到该结点所经分支上的所有结点,不包括其本身。
根结点无祖先,因此,输入结点中有根结点时,应输出“找不到这两个结点的共同祖先”。
解决方法:
在主函数中添加if判断语句,当p或q指针指向的数据与根结点值相等时,输出“找不到这两个结点的共同祖先”。
4.2程序执行过程
以下面所给二叉树为例,程序执行过程中用‘#’代替空格以使结果更清晰。
<<<<<<<欢迎进入二叉树结点共同祖先求值系统>>>>>>>
请用先序遍历创建一棵二叉树:
ABD##EG###C#F##↙
该二叉树先序遍历序列为:
ABDEGCF
请输入要查找共同祖先的两个结点:
DE↙
这两个结点的共同祖先为:
BA
Pressanykeytocontinue
参考文献
[1]严蔚敏,吴伟民.数据结构[M].北京:
清华大学出版社,2007.
[2]张长海,陈娟.C程序设计[M].北京:
高等教育出版社,2004.
[3]谭浩强.C程序设计[M].北京:
清华大学出版社,2005.
[4]王为青,张圣亮.C语言实战105例[M].北京:
人民邮电出版社,2007.
[5]王敬华,林萍,张清国.C语言程序设计教程[M].北京:
清华大学出版社,2009.
[6]王梦菊,齐景嘉.数据结构习题与实训教程[M].北京:
清华大学出版社,2011.
[7]吕国英.算法设计与分析[M].北京:
清华大学出版社,2006.
附录(关键部分程序清单)
程序代码
#include
#include
#defineMAXSIZE100
typedefstructnode{
chardata;
structnode*lchild,*rchild;
}treenode,*bintree;
typedefstructstack{
bintreedata[MAXSIZE];
inttag[MAXSIZE];
inttop;
}seqstack;
voidpush(bintreet,seqstack*s){
s->data[s->top]=t;
s->top++;
}
voidpop(seqstack*s,bintree&p){
if(s->top!
=0)
{
s->top--;
p=s->data[s->top];
}
elsep=NULL;
}
voidcreatree(bintree&p){//先序遍历创建二叉树p
charch;
ch=getchar();
if(ch=='')p=NULL;
else
{
p=(bintree)malloc(sizeof(treenode));
p->data=ch;
creatree(p->lchild);
creatree(p->rchild);
}
}
voidpreorder(bintreep){//先序遍历该二叉树
if(p)
{
printf("%c",p->data);
preorder(p->lchild);
preorder(p->rchild);
}
}
intfind(bintreep,bintreex,seqstack*s){//查找祖先并入栈
s->top=0;
while(p||s->top)
{
if(p)
{
s->tag[s->top]=0;
push(p,s);
p=p->lchild;
}
else
{
if(s->top&&s->tag[s->top-1])
{
pop(s,p);
if(p&&p->data==x->data)returns->top;
p=NULL;
}
else
{
p=s->data[s->top-1];
s->tag[s->top-1]=1;
p=p->rchild;
}
}
}
return-1;
}
voidAncestor(seqstack*sq,seqstack*sp){//共同祖先出栈、输出;若无,则不输出
bintreep;
while(sq->top!
=sp->top)
{
if((sq->top-1)>(sp->top-1))pop(sq,p);
elsepop(sp,p);
}
while(sp->top)
{
if(sq->data[sq->top-1]==sp->data[sp->top-1])
printf("%4c",sq->data[sq->top-1]->data);
pop(sq,p);
pop(sp,p);
}
}
voidmain(){
bintreeroot,p,q;
seqstack*sp,*sq;
intx,y;
root=(bintree)malloc(sizeof(treenode));
p=(bintree)malloc(sizeof(treenode));
q=(bintree)malloc(sizeof(treenode));
sq=(seqstack*)malloc(sizeof(seqstack));
sp=(seqstack*)malloc(sizeof(seqstack));
printf("<<<<<<<欢迎进入二叉树结点共同祖先求值系统>>>>>>>\n\n\n");
printf("请用先序遍历创建一棵二叉树:
\n");
creatree(root);
printf("该二叉树先序遍历序列为:
");
preorder(root);
printf("\n");
printf("\n请输入要查找共同祖先的两个结点:
\n");
getchar();
scanf("%c%c",&p->data,&q->data);
x=find(root,p,sp);
y=find(root,q,sq);
if(x==-1||y==-1)
printf("输入结点不存在!
");
elseif(p->data==root->data||q->data==root->data)
printf("找不到这两个结点的共同祖先!
");
else{
printf("这两个结点的共同祖先为:
");
Ancestor(sq,sp);
}
printf("\n");
}
课程设计总结:
本次课程设计中我学到了很多,不仅巩固了以前的知识,还提高了灵活和综合运用所学知识来分析、解决实际问题的能力,培养了我独立思考,深入研究,分析问题、解决问题的能力。
在对程序的修改过程中,对数据结构的理解有所加深,对数据结构的学习和提高很有益处。
在本次课程设计中,我深刻认识到了自己还有太多的基本思想没有真正的理解。
在以后的学习过程中,要认真进行上机实验,在实践中锻炼自己。
写程序的过程中要严谨,有耐心,慢慢加深对数据结构的理解与掌握。
在课余时间要多写程序,熟练掌握在调试程序过程中所遇到的常见错误,以后尽量避免出现这样的错误。
通过这次课程设计,我受益匪浅,我深深认识到,要学好一门学科,没有刻苦钻研的精神是不行的,只有在不断的尝试中经历失败,从失败中总结经验,然后再不断地尝试,才能获得成功。
我也意识到要做一名IT精英,背后的努力与汗水是必不可少的,我会认真学习专业课程,多做程序,多调试,来理解计算机语言,不断提高自己,成为社会所需要的人。
指导教师评语:
指导教师(签字):
年月日
课程设计成绩
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 共同 祖先 求解 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)