线索二叉树生成及其遍历_第1页
线索二叉树生成及其遍历_第2页
线索二叉树生成及其遍历_第3页
线索二叉树生成及其遍历_第4页
线索二叉树生成及其遍历_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、数据结构课程设计题 目: 线索二叉树的生成及其遍历 学 院: 理学院 班 级: 数学13-2班 学 生 姓 名:孙晴、张炳赫、张美娜、董自鹏 学 生 学 号: 8、12、13、22 指 导 教 师: 张太发 2014 年 12月 24日课程设计任务书姓名X y z s班级设计题目线索二叉树的生成及其遍历理论要点二叉树的遍历本质上是将一个复杂的非线性结构转换为线性结构,使每个结点都有且仅有一个直接前驱结点和直接后继结点(第一个结点无前驱,最后一个结点无后继)。但是二叉树中每个结点在这个序列中的直接前驱结点和直接后继结点是什么?二叉树的存储结构中并没有反映出来,只能在对二叉树遍历的动态过程中得到这

2、些信息。为了保留结点在某种遍历序列中直接前驱喝直接后继的位置信息,有两种方法。一是在结点结构中增加向前和向后的指针fwd和bkd,这种方法增加了存储开销,不可取;二是利用二叉树的二叉链表的那些空指针域来指示。建立线索二叉树,或者说对二叉树线索化,实质上就是遍历一棵二叉树。在遍历过程中,访问结点的操作是检查当前的左,右指针域是否为空,将它们改为指向前驱结点或后续结点的线索。为实现这一过程,设指针pre始终指向刚刚访问的结点,即若指针p指向当前结点,则pre指向它的前驱,以便设线索。 另外,在对一颗二叉树加线索时,必须首先申请一个头结点,建立头结点与二叉树的根结点的指向关系,对二叉树线索化后,还需

3、建立最后一个结点与头结点之间的线索。中序线索二叉树:若结点的ltag=1,lchild指向其前驱;否则,该结点的前驱是以该结点为根的左子树上按中序遍历的最后一个结点。若rtag=1,rchild指向其后继;否则,该结点的后驱是以该结点为根的右子树上按中序遍历的第一个结点。设计目标以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱结点和后继结点,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针 p 指向当前

4、访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法预期结果对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历。小组人员具体分工 s:报告填写 z:程序设计、运行 y:答辩 x:ppt设计制作计划与进步的安排在两周(共10天)内完成课程设计,具体安排如下: 1.查找所需要的相关资料,进行整理; 2天 2.系统学习相关理论和算法,设计总体流程; 2天 3.编写源代码,上机调试,并进行修改逐步完善代码; 3天 4.编写课程设计报告; 2天 5.进行后续整理工作。 1天目录摘要I1 题目分析1 1.1相关思想及概念介绍.1 1.2线索二叉树的结构.1 1.3需求分

5、析.2 2概要设计2 2.1抽象数据类型的定义.3 2.2主程序的流程.3 2.3各程序模块之间的层次(调用)关系.53详细设计64调试分析105用户使用说明106 测试结果117课程设计体会128 参考文献129 源程序13摘要针对以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针 p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建

6、立中序线索化链表的算法本文通过建立二叉树, 实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。关键词:二叉树,中序线索二叉树,中序线索二叉树的遍历II数据结构程序设计1 题目分析1.1 相关思想及概念介绍(1)二叉树遍历二叉树的遍历是指按照某种顺序访问二叉树中的每个结点,使每个结点被访问一次且仅被访问一次。遍历二叉树中经常要用到的一种操作。因为在实际应用问题中,常常需要按一定顺序对二叉树中的每个结点逐个进行访问,查找具有某一特点的结点,然后对这些满足条件的结点进行处理。通过一次完整的遍历,可使二叉树中结点信息由非线性排列

7、变为某种意义上的线性序列。也就是说,遍历操作使非线性结构线性化。由二叉树的定义可知,一棵二叉树由根结点、根结点的左子树和根结点的右子树三部分组成。因此,只要依次遍历这三部分,就可以遍历整个二叉树。若以D、L、R分别表示访问根结点、遍历根结点的左子树、遍历根结点的右子树,则二叉树的遍历方式有6种:DLR、LDR、LRD、DRL、RDL、和RLD。如果限定先左后右,则只有前三种方式,即DLR(先序遍历)、LDR(中序遍历)和LRD(后序遍历)。(1)线索二叉树按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排列为一个线性序列。在该序列中,除第一个结点外,每个结点有且仅有一个直接前驱结点;除

8、最后一个结点外,每个结点有且仅有一个直接后继结点。但是,二叉树中每个结点在这个序列中的直接前驱结点和直接后继结点是什么,二叉树的存储结构中并没有反映出来,只能在对二叉树遍历的动态过程中得到这些信息,可以利用二叉树的二叉链表存储结构中的那些空指针域来指示。这些指向直接前驱结点和指向直接后继结点的指针被称为线索,借了线索的二叉树成为线索二叉树。线索二叉树将为二叉树的遍历提供许多方便。1.2 线索二叉树的结构1、n个结点有n-1个前驱和n-1个后继;一共有2n个链域,其中:n+1个空链域,n-1个指针域;因此, 可以用空链域来存放结点的前驱和后继。线索二叉树就是利用n+1个空链域来存放结点的前驱和后

9、继结点的信息。2、线索:有效利用二叉链表中空的存储空间,指定原有的孩子指针为空的域来存放指向前驱和后继的信息,这样的指针被称为“线索”。加线索的过程称为线索化,由此得到的二叉树称作线索二叉树。若结点有左子树,则左链域lchild指示其左孩子(ltag=0);否则,令左链域指示其前驱(ltag=1);若结点有右子树,则右链域rchild指示其右孩子(rtag=0);否则,令右链域指示其后继(rtag=1);增设一个头结点,令其lchild指向二叉树的根结点,ltag=0、rtag=1;并将该结点作为遍历访问的第一个结点的前驱和最后一个结点的后继;最后用头指针指示该头结点。其rchild域的指针指

10、向中序遍历时访问的最后一个结点;反之,令二叉树中序序列中的第一个结点的lchild域指针和最后一个结点rchild域的指针均指向头结点,这好比为二叉树建立了一个双向线索链表,既可以从第一个结点起顺后继进行遍历,也可以从最后一个结点起顺前驱进行遍历。3、例子:如下图a示的二叉树,其中序线索二叉树为图b所示:1.3 需求分析以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚

11、访问过的结点,若指针 p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法本文通过建立二叉树, 实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。主要任务:1.建立二叉树; 2.将二叉树进行中序线索化;3.编写程序,运行并修改; 4.利用中序线索遍历二叉树 5.书写课程设计论文并将所编写的程序完善。2 概要设计2.1抽象数据类型的定义二叉树的存储结构struct node ElemenType data; /数据域int ltag; /左标志域int rtag; /右标志域struct

12、 node *lchild; /左指针域struct node *rchild; /右指针域BTree;2.2主程序的流程 NNCTRL+CYYYNYYYYNNN选择菜单输出广义表形式,前(中,后)递归遍历定义线索二叉树创建线索二叉树开始输入(13)123其他前续非递归中序非递归后序非递归输入想查找的结点(有无此结点)输入想查找的结点输入想查找的 结点后继结点后继结点后继结点二叉树无此结点结束2.3各程序模块之间的层次(调用)关 3 详细设计(一)算法的C语言实现#include "stdio.h"#include "stdlib.h"#define O

13、K 1typedef char TElemType;typedef int Status;typedef enum PointerTag Link,Thread; /link=0:pointer,Thread=1:threadtypedef struct BiThrNodeTElemType data;struct BiThrNode *lchild,*rchild;PointerTag LTag,RTag;BiThrNode,*BiThrTree; BiThrTree pre; / 全局变量,始终指向刚刚访问过的结点 void InThreading(BiThrTree p)if(p) In

14、Threading(p->lchild);/左子树线索化 if(!p->lchild)p->LTag=Thread;p->lchild=pre;/前驱线索 if(!pre->rchild)pre->RTag=Thread;pre->rchild=p;/后续线索 pre=p; /保持pre指向p的前驱 InThreading(p->rchild);/右子树线索化 /if/InThreading Status InOrderThreading(BiThrTree &Thrt,BiThrTree T)/中序遍历二叉树,并将其中序线索化,Thrt

15、指向头结点/BiThrTree Thrt;if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode) exit(-1);Thrt->LTag=Link; /建立头结点Thrt->RTag=Thread; /右指针回指Thrt->rchild=Thrt;if(!T) Thrt->rchild=Thrt; /若二叉树为空,则左指针回指else Thrt->lchild=T; pre=Thrt; InThreading(T); /中序遍历进行中序线索化 pre->rchild=Thrt;/最后一个结点线索化 pre->RTag

16、=Thread; Thrt->rchild=pre; return OK;/InOrderThreading Status InOrderTraverse_Thr(BiThrTree T)/T指向头结点,头结点的左链lchild指向根结点,非递归算法BiThrTree p;p=T->lchild;while(p!=T) /空树或遍历结束时,Tp while(p->LTag=Link) p=p->lchild; printf("%cn",p->data); /访问其左子树为空的结点 while(p->RTag=Thread&&

17、;p->rchild!=T) p=p->rchild; printf("%cn",p->data); /访问后续结点 /while p=p->rchild; /whilereturn OK;/InOrderT_Thr Status CreateBitree(BiThrTree &T)/按先序次序输入二叉树char ch,enter;scanf("%c%c",&ch,&enter);if(ch=' ') T=NULL;else if(!(T=(BiThrTree)malloc(sizeof(B

18、iThrNode) exit(1); T->data=ch; CreateBitree(T->lchild); CreateBitree(T->rchild); /elsereturn OK;/CreateBitree int main()BiThrTree T,Thrt;CreateBitree(T);/创建InOrderThreading(Thrt,T);/线索化InOrderTraverse_Thr(Thrt);/遍历访问return OK;注意点:在输入字符创立二叉树时,要注意叶子结点的输入形式,即叶子结点的左右空指针也要输入,在我们这里输入空格。(二)建立中序二叉树

19、的递归算法,其中pre为全局变量。 BiThrNodeType *pre; BiThrTree InOrderThr(BiThrTree T) /*中序遍历二叉树T,并将其中序线索化,pre为全局变量*/ BiThrTree head; head=(BitThrNodeType *)malloc(sizeof(BiThrType);/*设申请头结点成功*/ head->ltag=0;head->rtag=1;/*建立头结点*/ head->rchild=head;/*右指针回指*/ if(!T)head->lchild=head;/*若二叉树为空,则左指针回指*/ el

20、sehead->lchild=T;pre=head; InThreading(T);/*中序遍历进行中序线索化*/ pre->rchild=head; pre->rtag=1;/*最后一个结点线索化*/ head->rchild=pre; ; return head; void InThreading(BiThrTree p) /*通过中序遍历进行中序线索化*/ if(p) InThreading(p->lchild);/*左子树线索化*/ if(p->lchild=NULL)/*前驱线索*/ p->ltag=1; p->lchild=pre;

21、if(p->rchild=NULL)p->rtag=1;/*后驱线索*/ if(pre!=NULL && pre->rtag=1) pre->rchild=p; pre=p; InThreading(p->rchild);/*右子树线索化*/ 进行中序线索化的算法:bithptr*pre; /* 全程变量*/ voidINTHREAD(bithptr *p) if(p!=NULL) INTHREAD(p->lchild); /* 左子树线索化*/ if(p->lchild=NULL) p->ltag=1;p->lchild=

22、pre; if(p->rchild=NULL) p->rtag=1; if(pre!=NULL && pre->rtag=1)pre->rchild=p; pre=p; /* 前驱指向当前结点*/ INTHREAD(p->rchild); /* 右子树线索化*/ 4 调试分析该程序在调试过程中遇到的问题是:对已学知识运用能力欠缺,尤其是在编程方面,由于C语言等计算机基础课程知识没有很好的掌握同时在学习数据结构时也没有真正弄懂导致编程时小错误不断,而且在遇到许多小的错误时靠自己很难再调整过来,但整体上是一次对所学知识的运用巩固,特别是对二叉树的建立以

23、及对它进行线索方面,翻阅大量的书籍及搜集资料并求教于计算机系的同学,才找到一些解决问题的方法,在用中序遍历线索二叉树时总是搞混不过也因此让我对前序,中序,后序遍历更加理解。同时,在经历了很多次修改重写课程设计报告的悲惨经历后,懂得了很多关于办公软件方面的知识尤其是自己做的东西一定要保存并备份。主要出现了两方面问题:A. 语法错误(经过多次调试发现有一处缺少了引号)B. 逻辑错误。声明一个指针只是在内存中开辟了一个这种数据类型的空间,并让这个指针指向它,由于它还没有指向任何变量,因此不能引用其指向的任何成员。5 用户使用使用该程序时在打开程序的主界面后,输入相应要求的输入形式,然后就输出中序遍历

24、,方便简洁。例如:运行时,分别输入(前序输入):1 2 3 0 0 4 0 5 0 0 6 0 0建立如下所示的二叉树:                      1                  2 &#

25、160;     6               3     4                        5 中序

26、遍历输出:3  2  4  5  1  66 测试结果运行时,分别输入(前序输入):1 2 3 0 0 4 0 5 0 0 6 0 0建立如下所示的二叉树:                      1           

27、60;      2       6               3     4                 

28、60;      5 中序遍历输出:3  2  4  5  1  67 结论体会在这次的课程设计中,我们明白了理论和实际还是相差很大的,理论知识能学明白单不代表程序就能编出来,大多数情况下,我们还是不具备完成这项项目的能力的。它需要我们不仅能够将以前学过的知识与现学的知识融会贯通同时还要求我们学会怎样如何整合做项目所需要的全部知识以及对为学知识的查询及自学能力。更重要的时它还要求我们敢于实践勤于动手,遇到有些不会处理的,我们会上网去查,或者去问老师,或者去问同学。例如以前我们对二叉树的

29、相关内容并不是很熟悉,但经过这次课程设计后现在我们不仅掌握了它们的使用方法,更重要的是我们学会了如何去学习,然后快速地应用到我们所需要的项目当中。同时我们还得到了很多关于本门课程的体会:在编写程序的过程中,把整个系统的框架准确的描述出来是非常重要的而且写程序是需要步步为营不然一不小心就会出错。我们们的C语言老师曾经说过良好的代码风格是成功的一半。例如在写代码时会有大量的小括号,大括号等,老师曾说这些代码在书写时一定要同时写一对,这样就可以避免丢掉或忘写其中的一个。真的是深有体会啊!还有在编码的过程中需要时常进行修改,如果程序的可读性不强,代码量又庞大的话,那么对于我们们来说是一件非常不幸的事情

30、,程序反复的改来改去是非常繁琐的。因此我们们一定要养成良好的书写代码的习惯。总之,通过一次的课程设计,我们不仅对我们所设计的内容有了更深的了解同时这门课程的知识掌握也更加牢固了,而且还学到很多关于办公软件方面的知识更重要的是通过和计算机方面的老师和同学的交流了解到了很多关于计算机方面及计算机相关工作的一些知识这位我们在选方向时提供了很珍贵的意见。总而言之这次收获颇多!8 参考文献1.严蔚敏,吴伟民 数据结构C语言版 :清华大学出版社 ,20092.谭浩强著.C程序设计(第三版).北京:清华大学出版社,20053.于海英,王国权编著的C语言程序设计.清华大学出版社2012年版4.备注:还有一些是

31、通过查找网站内容搜索整理的。9 源程序#include <stdio.h>#include <malloc.h>typedef enumLink,Thread PointerTag; /指针标志typedef int DataType;typedef struct BiThreTree /定义结点元素 PointerTag LTag,RTag; DataType data; struct BiThreTree *lchild,*rchild; BiThreTree;BiThreTree *pre; /全局变量,用于二叉树的线索化BiThreTree *CreateTree() /按前序输入建立二叉树 BiThreTree *T; DataType e; scanf("%d",&e); if(e=0) T=NULL; else T=(BiThreTree *)malloc(sizeof(BiThreTree); T->data=e; T->LTag=Link; /初始化时指针标志均为Link T->RTag=Link; T->lchild=CreateTree(); T-&

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论