线索二叉树生成及其遍历

线索二叉树生成及其遍历
线索二叉树生成及其遍历

数据结构课程设计

题目: 线索二叉树的生成及其遍历

学院:理学院

班级:数学13-2班

学生姓名:孙晴、张炳赫、张美娜、董自鹏

学生学号: 8、12、13、22 指导教师:张太发

2014 年 12月 24日

课程设计任务书

姓名X y z s 班级设计题目线索二叉树的生成及其遍历

理论要点

二叉树的遍历本质上是将一个复杂的非线性结构转换为线

性结构,使每个结点都有且仅有一个直接前驱结点和直接后继结点(第一个结点无前驱,最后一个结点无后继)。但是二叉树中每个结点在这个序列中的直接前驱结点和直接后继结点是什

么?二叉树的存储结构中并没有反映出来,只能在对二叉树遍历的动态过程中得到这些信息。为了保留结点在某种遍历序列中直接前驱喝直接后继的位置信息,有两种方法。一是在结点结构中增加向前和向后的指针fwd和bkd,这种方法增加了存储开销,不可取;二是利用二叉树的二叉链表的那些空指针域来指示。

建立线索二叉树,或者说对二叉树线索化,实质上就是遍历一棵二叉树。在遍历过程中,访问结点的操作是检查当前的左,右指针域是否为空,将它们改为指向前驱结点或后续结点的线索。为实现这一过程,设指针pre始终指向刚刚访问的结点,即若指针p指向当前结点,则pre指向它的前驱,以便设线索。

另外,在对一颗二叉树加线索时,必须首先申请一个头结点,建立头结点与二叉树的根结点的指向关系,对二叉树线索化后,还需建立最后一个结点与头结点之间的线索。

中序线索二叉树:若结点的ltag=1,lchild指向其前驱;否则,该结点的前驱是以该结点为根的左子树上按中序遍历的最后一

个结点。若rtag=1,rchild指向其后继;否则,该结点的后驱是以该结点为根的右子树上按中序遍历的第一个结点。

设计目标

以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱结点和后继结点,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针 p 指向当前访问的结点,则 pre 指向它的前驱。由此得到中序遍历建立中序线索化链表的算法

预期结果对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历。

小组人员具体分工?s:报告填写

?z:程序设计、运行?y:答辩

?x:ppt设计制作

计划与进步的安排在两周(共10天)内完成课程设计,具体安排如下:

1.查找所需要的相关资料,进行整理; 2天

2.系统学习相关理论和算法,设计总体流程; 2天

3.编写源代码,上机调试,并进行修改逐步完善代码; 3天

4.编写课程设计报告; 2天

5.进行后续整理工作。 1天

目录

摘要................................ 错误!未定义书签。

1 题目分析......................... 错误!未定义书签。

1.1相关思想及概念介绍 (1)

1.2线索二叉树的结构 (1)

1.3需求分析 (2)

2 概要设计 (2)

2.1抽象数据类型的定义 (3)

2.2主程序的流程 (3)

2.3各程序模块之间的层次(调用)关系 (5)

3 详细设计 (6)

4 调试分析 (10)

5 用户使用说明 (10)

6 测试结果 (11)

7 课程设计体会 (12)

8 参考文献 (12)

9 源程序 (13)

摘要

针对以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针 p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法本文通过建立二叉树,实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。

关键词:二叉树,中序线索二叉树,中序线索二叉树的遍历

1 题目分析

1.1 相关思想及概念介绍

(1)二叉树遍历

二叉树的遍历是指按照某种顺序访问二叉树中的每个结点,使每个结点被访问一次且仅被访问一次。

遍历二叉树中经常要用到的一种操作。因为在实际应用问题中,常常需要按一定顺序对二叉树中的每个结点逐个进行访问,查找具有某一特点的结点,然后对这些满足条件的结点进行处理。

通过一次完整的遍历,可使二叉树中结点信息由非线性排列变为某种意义上的线性序列。也就是说,遍历操作使非线性结构线性化。

由二叉树的定义可知,一棵二叉树由根结点、根结点的左子树和根结点的右子树三部分组成。因此,只要依次遍历这三部分,就可以遍历整个二叉树。若以D、L、R分别表示访问根结点、遍历根结点的左子树、遍历根结点的右子树,则二叉树的遍历方式有6种:DLR、LDR、LRD、DRL、RDL、和RLD。如果限定先左后右,则只有前三种方式,即DLR(先序遍历)、LDR(中序遍历)和LRD(后序遍历)。

(1)线索二叉树

按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排列为一个线性序列。在该序列中,除第一个结点外,每个结点有且仅有一个直接前驱结点;除最后一个结点外,每个结点有且仅有一个直接后继结点。但是,二叉树中每个结点在这个序列中的直接前驱结点和直接后继结点是什么,二叉树的存储结构中并没有反映出来,只能在对二叉树遍历的动态过程中得到这些信息,可以利用二叉树的二叉链表存储结构中的那些空指针域来指示。这些指向直接前驱结点和指向直接后继结点的指针被称为线索,借了线索的二叉树成为线索二叉树。

线索二叉树将为二叉树的遍历提供许多方便。

1.2 线索二叉树的结构

1、n个结点有n-1个前驱和n-1个后继;一共有2n个链域,其中:n+1个空链域,n-1个指针域;因此, 可以用空链域来存放结点的前驱和后继。线索二叉树就是利用n+1个空链域来存放结点的前驱和后继结点的信息。

2、线索:有效利用二叉链表中空的存储空间,指定原有的孩子指针为空的域来存放指向前驱和后继的信息,这样的指针被称为“线索”。加线索的过程称为线索化,由此得到的二叉树称作线索二叉树。

若结点有左子树,则左链域lchild指示其左孩子(ltag=0);否则,令左链域指示其前驱(ltag=1);

若结点有右子树,则右链域rchild指示其右孩子(rtag=0);否则,令右链域指示其后继(rtag=1);

增设一个头结点,令其lchild指向二叉树的根结点,ltag=0、rtag=1;并将该结点作为遍历访问的第一个结点的前驱和最后一个结点的后继;最后用头指针指示该头结点。其rchild域的指针指向中序遍历时访问的最后一个结点;反之,令二叉树中序序列中的第一个结点的lchild域指针和最后一个结点rchild 域的指针均指向头结点,这好比为二叉树建立了一个双向线索链表,既可以从第一个结点起顺后继进行遍历,也可以从最后一个结点起顺前驱进行遍历。

3、例子:如下图a示的二叉树,其中序线索二叉树为图b所示:

1.3 需求分析

以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,并且利用结点的空链域存放(线索链表)。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针 p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法本文通过建立二叉树,实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。主要任务:

1.建立二叉树;

2.将二叉树进行中序线索化;

3.编写程序,运行并修改;

4.利用中序线索遍历二叉树

5.书写课程设计论文并将所编写的程序完善。

2 概要设计2.1抽象数据类型的定义

二叉树的存储结构

struct node

{ ElemenType data; //数据域int ltag; //左标志域

int rtag; //右标志域

struct node *lchild; //左指针域

struct node *rchild; //右指针域}

BTree;

2.2主程序的流程

2.3各程序模块之间的层次(调用)关

N

CTRL+C

Y

Y

Y N

Y

Y Y Y N

N

N 选择菜单 输出广义表形式,前(中,后)递归遍历

定义线索二叉树 创建线索二叉树

开始 输入(1~3) 1

2

3

其他

前续非递归

中序非递归

后序非递归

输入想查找的结点(有无此结

输入想查找的结点

输入想查找的 结点

后继结点 后继结点 后继结点

3 详细设计

(一)算法的C语言实现

#include "stdio.h"

#include "stdlib.h"

#define OK 1

typedef char TElemType;

typedef int Status;

typedef enum PointerTag {Link,Thread};

//link==0:pointer,Thread==1:thread

typedef struct BiThrNode

{

TElemType data;

struct BiThrNode *lchild,*rchild;

PointerTag LTag,RTag;

}BiThrNode,*BiThrTree;

BiThrTree pre; // 全局变量,始终指向刚刚访问过的结点

void InThreading(BiThrTree p)

{

if(p)

{

InThreading(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指向头结点

//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=Thread;

Thrt->rchild=pre;

}

return OK;

}//InOrderThreading

Status InOrderTraverse_Thr(BiThrTree T)

{

//T指向头结点,头结点的左链lchild指向根结点,非递归算法BiThrTree p;

p=T->lchild;

while(p!=T) //空树或遍历结束时,T==p

{

while(p->LTag==Link) p=p->lchild;

printf("%c\n",p->data); //访问其左子树为空的结点

while(p->RTag==Thread&&p->rchild!=T)

{

p=p->rchild;

printf("%c\n",p->data); //访问后续结点

}//while

p=p->rchild;

}//while

return 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(BiThrNode)))) exit(1);

T->data=ch;

CreateBitree(T->lchild);

CreateBitree(T->rchild);

}//else

return OK;

}//CreateBitree

int main()

{

BiThrTree T,Thrt;

CreateBitree(T);//创建

InOrderThreading(Thrt,T);//线索化

InOrderTraverse_Thr(Thrt);//遍历访问

return OK;

}

注意点:在输入字符创立二叉树时,要注意叶子结点的输入形式,即叶子结点的左右空指针也要输入,在我们这里输入空格。

(二)建立中序二叉树的递归算法,其中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;/*若二叉树为空,则左指针回指*/ else{head->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;

}

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=pre;}

if(p->rchild==NULL) p->rtag=1;

if(pre!=NULL && pre->rtag==1)pre->rchild=p;

pre=p; /* 前驱指向当前结点*/

INTHREAD(p->rchild); /* 右子树线索化*/

}

4 调试分析

该程序在调试过程中遇到的问题是:对已学知识运用能力欠缺,尤其是在编程方面,由于C语言等计算机基础课程知识没有很好的掌握同时在学习数据结构时也没有真正弄懂导致编程时小错误不断,而且在遇到许多小的错误时靠自己很难再调整过来,但整体上是一次对所学知识的运用巩固,特别是对二叉树的建立以及对它进行线索方面,翻阅大量的书籍及搜集资料并求教于计算机系的同学,才找到一些解决问题的方法,在用中序遍历线索二叉树时总是搞混不过也因此让我对前序,中序,后序遍历更加理解。同时,在经历了很多次修改重写课程设计报告的悲惨经历后,懂得了很多关于办公软件方面的知识尤其是自己做的东西一定要保存并备份。

主要出现了两方面问题:

A.语法错误(经过多次调试发现有一处缺少了引号)

B.逻辑错误。声明一个指针只是在内存中开辟了一个这种数据类型的空间,并让这个指针指向它,由于它还没有指向任何变量,因此不能引用其指向的任何成员。

5 用户使用

使用该程序时在打开程序的主界面后,输入相应要求的输入形式,然后就输出中序遍历,方便简洁。

例如:运行时,分别输入(前序输入):1 2 3 0 0 4 0 5 0 0 6 0 0

建立如下所示的二叉树:

1

2 6

3 4

5

中序遍历输出:3 2 4 5 1 6

6 测试结果

运行时,分别输入(前序输入):1 2 3 0 0 4 0 5 0 0 6 0 0 建立如下所示的二叉树:

1

2 6

3 4

5

中序遍历输出:3 2 4 5 1 6

7 结论体会

在这次的课程设计中,我们明白了理论和实际还是相差很大的,理论知识能学明白单不代表程序就能编出来,大多数情况下,我们还是不具备完成这项项目的能力的。它需要我们不仅能够将以前学过的知识与现学的知识融会贯通同时还要求我们学会怎样如何整合做项目所需要的全部知识以及对为学知识的查询及

自学能力。更重要的时它还要求我们敢于实践勤于动手,遇到有些不会处理的,我们会上网去查,或者去问老师,或者去问同学。例如以前我们对二叉树的相关内容并不是很熟悉,但经过这次课程设计后现在我们不仅掌握了它们的使用方法,更重要的是我们学会了如何去学习,然后快速地应用到我们所需要的项目当中。

同时我们还得到了很多关于本门课程的体会:在编写程序的过程中,把整个系统的框架准确的描述出来是非常重要的而且写程序是需要步步为营不然一不

小心就会出错。我们们的C语言老师曾经说过良好的代码风格是成功的一半。例如在写代码时会有大量的小括号,大括号等,老师曾说这些代码在书写时一定要同时写一对,这样就可以避免丢掉或忘写其中的一个。真的是深有体会啊!还有在编码的过程中需要时常进行修改,如果程序的可读性不强,代码量又庞大的话,那么对于我们们来说是一件非常不幸的事情,程序反复的改来改去是非常繁琐的。因此我们们一定要养成良好的书写代码的习惯。

总之,通过一次的课程设计,我们不仅对我们所设计的内容有了更深的了解同时这门课程的知识掌握也更加牢固了,而且还学到很多关于办公软件方面的知识更重要的是通过和计算机方面的老师和同学的交流了解到了很多关于计算机

方面及计算机相关工作的一些知识这位我们在选方向时提供了很珍贵的意见。总而言之这次收获颇多!

8 参考文献

1.严蔚敏,吴伟民.《数据结构C语言版》:清华大学出版社,2009

2.谭浩强著.《C程序设计》(第三版).北京:清华大学出版社,2005

3.于海英,王国权编著的《C语言程序设计》.清华大学出版社2012年版

4.备注:还有一些是通过查找网站内容搜索整理的。

9 源程序

#include

#include

typedef enum{Link,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->rchild=CreateTree();

}

return T;

}

void InThread(BiThreTree *T)

{

BiThreTree *p;

p=T;

if(p)

{

InThread(p->lchild);

if(!p->lchild)

{ p->LTag=Thread;

p->lchild=pre;

}

if(!pre->rchild)

{ pre->RTag=Thread;

pre->rchild=p;

}

pre=p;

InThread(p->rchild);

}

}

BiThreTree *InOrderThrTree(BiThreTree *T) //中序线索化二叉树{

BiThreTree *Thre; //Thre为头结点的指针 Thre=(BiThreTree *)malloc(sizeof(BiThreTree));

Thre->lchild=T;

Thre->rchild=Thre;

pre=Thre;

InThread(T);

pre->RTag=Thread;

pre->rchild=Thre;

Thre->rchild=pre;

return Thre;

}

void InThrTravel(BiThreTree *Thre) //中序遍历二叉树

{

BiThreTree *p;

p=Thre->lchild;

while(p!=Thre) //指针回指向头结点时结束 {

while(p->LTag==Link)

p=p->lchild;

printf("%4d",p->data);

while(p->RTag==Thread&&p->rchild!=Thre)

{p=p->rchild;

printf("%4d",p->data);

}

p=p->rchild;

}

}

int main()

{

BiThreTree *T,*Thre;

T=CreateTree();

Thre=InOrderThrTree(T);

InThrTravel(Thre);

system("pause");

}

创建一个二叉树并输出三种遍历结果

实验报告 课程名称数据结构 实验项目实验三--创建一个二叉树并输出三种遍历结果 系别■计算机学院 _________________ 专业_______________ 班级/学号_____________ 学生姓名___________ 实验日期— 成绩______________________________ 指导 教师

实验题目:实验三创建一个二叉树并输出三种遍历结果 实验目的 1)掌握二叉树存储结构; 2)掌握并实现二叉树遍历的递归算法和非递归算法; 3)理解树及森林对二叉树的转换; 4)理解二叉树的应用一哈夫曼编码及WPL计算。 实验内容 1)以广义表或遍历序列形式创建一个二叉树,存储结构自选; 2)输出先序、中序、后序遍历序列; 3)二选一应用题:1)树和森林向二叉树转换;2)哈夫曼编码的应用问题。 题目可替换上述前两项实验内容) 设计与编码 1)程序结构基本设计框架 (提示:请根据所选定题目,描述程序的基本框架,可以用流程图、界面描述图、 框图等来表示) 2)本实验用到的理论知识遍历二叉树,递归和非递归的方法 (应用型

(提示:总结本实验用到的理论知识,实现理论与实践相结合。总结尽量简明扼要,并与本次实验密切相关,要求结合自己的题目并阐述自己的理解和想法) 3) 具体算法设计 1) 首先,定义二叉树的存储结构为二叉链表存储,每个元素的数 据类型Elemtype,定义一棵二叉树,只需定义其根指针。 2) 然后以递归的先序遍历方法创建二叉树,函数为CreateTree(),在输 入字符时要注意,当节点的左孩子或者右孩子为空的时候,应当输入一 个特殊的字符(本算法为“ #”),表示左孩子或者右孩子为空。 3) 下一步,创建利用递归方法先序遍历二叉树的函数,函数为 PreOrderTreeQ,创建非递归方法中序遍历二叉树的函数,函数为 InOrderTree(),中序遍历过程是:从二叉树的根节点开始,沿左子树 向下搜索,在搜索过程将所遇到的节点进栈;左子树遍历完毕后,从 栈顶退出栈中的节点并访问;然后再用上述过程遍历右子树,依次类 推,指导整棵二叉树全部访问完毕。创建递归方法后序遍历二叉树的 函数,函数为LaOrderTree()。 (提示:该部分主要是利用C、C++ 等完成数据结构定义、设计算法实现各种操作,可以用列表分步形式的自然语言描述,也可以利用流程图等描述) 4) 编码 #include #include #include typedef char DataType; #define MaxSize 100 typedef struct Node { DataType data; struct Node *lchild; struct Node *rchild; } *BiTree,BitNode;

二叉排序树的建立及遍历的实现

课程设计任务书 题目: 二叉排序树的建立及遍历的实现 初始条件: 理论:学习了《数据结构》课程,掌握了基本的数据结构和常用的算法; 实践:计算机技术系实验室提供计算机及软件开发环境。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1、系统应具备的功能: (1)建立二叉排序树; (2)中序遍历二叉排序树并输出排序结果; 2、数据结构设计; 3、主要算法设计; 4、编程及上机实现; 5、撰写课程设计报告,包括: (1)设计题目; (2)摘要和关键字; (3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、设计体会等; (4)结束语; (5)参考文献。 时间安排:2007年7月2日-7日(第18周) 7月2日查阅资料 7月3日系统设计,数据结构设计,算法设计 7月4日-5日编程并上机调试7月6日撰写报告 7月7日验收程序,提交设计报告书。 指导教师签名: 2007年7月2日 系主任(或责任教师)签名: 2007年7月2日 排序二叉树的建立及其遍历的实现

摘要:我所设计的课题为排序二叉树的建立及其遍历的实现,它的主要功能是将输入的数据 组合成排序二叉树,并进行,先序,中序和后序遍历。设计该课题采用了C语言程序设计,简洁而方便,它主要运用了建立函数,调用函数,建立递归函数等等方面来进行设计。 关键字:排序二叉树,先序遍历,中序遍历,后序遍历 0.引言 我所设计的题目为排序二叉树的建立及其遍历的实现。排序二叉树或是一棵空树;或是具有以下性质的二叉树:(1)若它的左子树不空,则作子树上所有的结点的值均小于它的根结点的值;(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它的左,右子树也分别为二叉排序树。对排序二叉树的建立需知道其定义及其通过插入结点来建立排序二叉树,遍历及其输出结果。 该设计根据输入的数据进行建立排序二叉树。对排序二叉树的遍历,其关键是运用递归 调用,这将极大的方便算法设计。 1.需求分析 建立排序二叉树,主要是需要建立节点用来存储输入的数据,需要建立函数用来创造排序二叉树,在函数内,需要进行数据比较决定数据放在左子树还是右子树。在遍历二叉树中,需要建立递归函数进行遍历。 该题目包含两方面的内容,一为排序二叉树的建立;二为排序二叉树的遍历,包括先序遍历,中序遍历和后序遍历。排序二叉树的建立主要运用了循环语句和递归语句进行,对遍历算法运用了递归语句来进行。 2.数据结构设计 本题目主要会用到建立结点,构造指针变量,插入结点函数和建立排序二叉树函数,求深度函数,以及先序遍历函数,中序遍历函数和后序遍历函数,还有一些常用的输入输出语句。对建立的函明确其作用,先理清函数内部的程序以及算法在将其应用到整个程序中,在建立排序二叉树时,主要用到建立节点函数,建立树函数,深度函数,在遍历树是,用到先序遍历函数,中序遍历函数和后序遍历函数。

数据结构——二叉树的操作(遍历及树形输出)

/*实验三:二叉树遍历操作验证*/ #include #include #include #include #include #include #include using namespace std; #define OK 1 #define ERROR 0 #define OVERFLOW -2 int LeafNum;//叶子结点个数 //定义结构体 typedef struct BiTNode{ char data; //存放值 struct BiTNode *lchild,*rchild; //左右孩子 }BiTNode,*BiTree; //先序输入二叉树结点的值,空格表示空树 void createBiTree(BiTree &T) { char ch; //输入结点时用 scanf("%c",&ch); if(ch==' ') //若输入空格,该值为空,且没有左右孩子 { T=NULL; }else{ T=(BiTNode *)malloc(sizeof(BiTNode)); //分配结点空间 if(!T) //分配失败 { exit(OVERFLOW); } T->data=ch; //生成根结点 createBiTree(T->lchild); //构造左子树 createBiTree(T->rchild); //构造右子树 } } //递归方法先序遍历二叉树 void preOrderTraverse(BiTree T) {

if(T) //若非空 { if(T->data) { //输出 printf("%c",T->data); } preOrderTraverse(T->lchild); preOrderTraverse(T->rchild); } } //递归方法中序遍历二叉树 void inOrderTraverse(BiTree T) { if(T) //若非空 { preOrderTraverse(T->lchild); if(T->data) { //输出 printf("%c",T->data); } preOrderTraverse(T->rchild); } } //递归方法后序遍历二叉树 void postOrderTraverse(BiTree T) { if(T) //若非空 { preOrderTraverse(T->lchild); preOrderTraverse(T->rchild); if(T->data) { //输出 printf("%c",T->data); } } } //层序遍历二叉树 void LevelTraverse(BiTree T) { queue q;//建队 q.push(T);//根节点入队

数据结构课程设计_线索二叉树的生成及其遍历

数据结构课程设计 题目: 线索二叉树的生成及其遍历 学院: 班级: 学生姓名: 学生学号: 指导教师: 2012 年12月5日

课程设计任务书

摘要 针对以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,但会使得结构的存储密度降低;并且利用结点的空链域存放(线索链表),方便。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法 本文通过建立二叉树,实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。 关键词二叉树,中序线索二叉树,中序线索二叉树的遍历

目录 摘要 ............................................ 错误!未定义书签。第一章,需求分析................................. 错误!未定义书签。第二章,概要设计 (1) 第三章,详细设计 (2) 第四章,调试分析 (5) 第五章,用户使用说明 (5) 第六章,测试结果 (5) 第七章,绪论 (6) 第八章,附录参考文献 (7)

线索二叉树的生成及其遍历 第一章需求分析 以二叉链表作为存储结构时,只能找到结点的左、右孩子的信息,而得不到结点的前驱与后继信息,为了使这种信息只有在遍历的动态过程中才能得到。增设两个指针分别指示其前驱和后继,但会使得结构的存储密度降低;并且利用结点的空链域存放(线索链表),方便。同时为了记下遍历过程中访问结点的先后关系,附设一个指针pre始终指向刚刚访问过的结点,若指针p 指向当前访问的结点,则 pre指向它的前驱。由此得到中序遍历建立中序线索化链表的算法 本文通过建立二叉树,实现二叉树的中序线索化并实现中序线索二叉树的遍历。实现对已生成的二叉树进行中序线索化并利用中序线索实现对二叉树的遍历的效果。主要任务: 1.建立二叉树; 2.将二叉树进行中序线索化; 3.编写程序,运行并修改; 4.利用中序线索遍历二叉树 5.书写课程设计论文并将所编写的程序完善。 第二章概要设计 下面是建立中序二叉树的递归算法,其中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;/*若二叉树为空,则左指针回指*/ else{head->lchild=T;pre=head; InThreading(T);/*中序遍历进行中序线索化*/ pre->rchild=head; pre->rtag=1;/*最后一个结点线索化*/ head->rchild=pre; }; return head; } void InThreading(BiThrTree p) {/*通过中序遍历进行中序线索化*/ if(p)

数据结构C语言实现二叉树三种遍历

实验课题一:将下图中得二叉树用二叉链表表示: 1用三种遍历算法遍历该二叉树,给出对应得输出结果; 2写一个函数对二叉树搜索,若给出一个结点,根据其就是否属于该树,输出true或者f alse。 3写函数完成习题4、31(C++版)或4、28(C版教科书)。 #include "stdio、h" #include”malloc、h" typedefstruct BiTNode { char data; structBiTNode *lchild,*rchild; }BiTNode,*BiTree; BiTree Create(BiTreeT) { char ch; ch=getchar(); if(ch=='#’) T=NULL; else { T=(BiTNode *)malloc(sizeof(BiTNode)); T-〉data=ch; T->lchild=Create(T—〉lchild); T—〉rchild=Create(T-〉rchild); } return T; } int node(BiTree T) { int sum1=0,a,b; ?if(T) { if(T!=NULL) ??sum1++;

?a=node(T->lchild); sum1+=a; b=node(T—>rchild); sum1+=b; ?} return sum1; } int mnode(BiTree T) { ?int sum2=0,e,f; if(T) { ?if((T->lchild!=NULL)&&(T-〉rchild!=NULL))?sum2++; ?e=mnode(T-〉lchild); sum2+=e; f=mnode(T-〉rchild); sum2+=f; ?} return sum2; } void Preorder(BiTree T) { if(T) { printf("%c”,T->data); Preorder(T—>lchild); Preorder(T-〉rchild); } } int Sumleaf(BiTree T) { int sum=0,m,n; if(T) { if((!T-〉lchild)&&(!T-〉rchild)) sum++; m=Sumleaf(T->lchild); sum+=m; n=Sumleaf(T—>rchild); sum+=n; } return sum; }

二叉树的建立及其遍历实验报告

数据结构实验报告 ———二叉树的建立及其遍历 一、实验目的 1、了解二叉树的建立的方法及其遍历的顺序,熟悉二叉树的三种遍历 2、检验输入的数据是否可以构成一颗二叉树 二、实验的描述和算法 1、实验描述 二叉树的建立首先要建立一个二叉链表的结构体,包含根节点和左右子树。因为耳熟的每一个左右子树又是一颗二叉树,所以可以用递归的方法来建立其左右子树。二叉树的遍历是一种把二叉树的每一个节点访问完并输出的过程,遍历时根结点与左右孩子的输出顺序构成了不同的遍历方法,这个过程需要按照不同的遍历的方法,先输出根结点还是先输出左右孩子,可以用选择语句实现。 2、算法 #include #include #define OVERFLOW 0 #define OK 1 #define ERROR 0 typedef struct BiTNode { char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; BiTree CreateBiTree(BiTree T)

{ scanf("%c",&e); if(e==' ') T=NULL; else { if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW); T->data=e; T->lchild=CreateBiTree(T->lchild); T->rchild=CreateBiTree(T->rchild); } return T; } /************************前序遍历***********************/ char PreOrderTraverse(BiTree T,char (* Visit)(char e)) { if(T) { if(Visit(T->data)) if(PreOrderTraverse(T->lchild,Visit)) if(PreOrderTraverse(T->rchild,Visit)) return OK; return ERROR; } else return OK; } char Visit(char e) { printf("%5c",e); return OK; } main() {

二叉树的随机生成及其遍历

叉树的随机生成及其遍历 张 zhaohan 10804XXXXX 2010/6/12 问题重述 利用随机函数产生50个(不大于1 00且各不相同的)随机整数,用这些整数来生成一棵二叉树,分别对二叉树 进行先根遍历,中根遍历和后根遍历并输出树中结点元素序列。 程序设计 (一) 需求分析: ?问题的定义与要求: 1 、产生50个不大于100且各不相同的随机整数 (由系统的随机函数生成并 对100取模);2、先根遍历并输出结果;3、中根遍历并输出结果;4、后根遍历并输出结果;按层次浏览二叉树结 5、点; 6、退出程序。 ?俞入:所需功能,选项为1?6。 ?输出:按照用户功能选择输出结果。 ?限制:输入的功能选择在1?6之间,否则无回应。 ?模块功能及要求: RandDif(): 生成50个随机不大于100的整数,每次生成不同随机整数。 CreateBitree(): 给数据结点生成二叉树,使每个结点的左右儿子指针指向左右儿子。 NRPreOrder(): 非递归算法的先根遍历。 inOrderTraverse(): 递归算法的中根遍历。 P ostOrderTraverseO:递归算法的后根遍历。 Welcome(): 欢迎窗口。 Menu():菜单。 Goodbye():再见窗口。 (二) 概要设计:

首先要生成二叉树,由于是对随机生成的50个数生成二叉树,故可以采取顺序存储的方式,对结点的左右儿子进行赋值。生成的二叉树是完全二叉树。 先根遍历的非递归算法: 1、根结点进栈 2、结点出栈,被访问 3、结点的右、左儿子(非空)进栈 4、反复执行2、3 ,至栈空为止。 先根遍历的算法流程图:根结点进栈( a[0]=T->boot,p=a[0] ) 访问结点printf(*p) 右儿子存在则进栈a[i]=(*p).rchild; i++; 左儿子存在则进栈a[i]=(*p).rchild; i++; 栈顶降低top--:i--;p=a[i]; 栈非空while(i>-1) 返回 中根遍历的递归算法流程图: T为空 Return; inOrderTraverse(T->lchild) Printf(T->data) inOrderTraverse(T->rchild) 返回

数据结构二叉树的创建及遍历

课程名称:数据结构实验 实验项目:二叉树的创建及遍历 姓名: 专业:计算机科学与技术 班级: 学号: 计算机科学与技术学院 20 17年11 月22 日

哈尔滨理工大学计算机科学与技术学院实验报告 实验项目名称:二叉树的建立及遍历 一、实验目的 1.熟悉掌握课本二叉树相关理论知识 2.实践与理论相结合,掌握二叉树的应用程序 3.学会二叉树的创建,遍历等其他基本操作的代码实现 二、实验内容 1.二叉树的创建代码实现 2.二叉树先序、中序、后序遍历代码实现 三、实验操作步骤 1.二叉树的建立 (1)树节点的定义 由于每个节点都由数据域和指左子树和右子树的指针,故结构体封装如下: typedef struct node { int data; struct node *left; struct node *right; }Tree,*bitree; (2)建立 采用递归的思想,先建立根再建立左子树,再建立右子树。递归截止条件子树为空,用-1代表树空 *T=(struct node *)malloc(sizeof(struct node));

(*T)->data=a; printf("%d的左节点",a); create(&(*T)->left); printf("%d的右节点",a); create(&(*T)->right); 2.三种遍历的实现 (1)先序遍历 依旧采用递归的思想,先遍历根后遍历左子树再遍历右子树。 printf("%d ",T->data); Pro(T->left); Pro(T->right); (2)中序遍历 先遍历左子树再遍历根最后遍历右子树 Mid(T->left); printf("%d ",T->data); Mid(T->right); (3)后序遍历 先遍历左子树再遍历右子树最后遍历根 Later(T->left); Later(T->right); printf("%d ",T->data); (4)按层遍历 按层遍历采用队列的思想,先将第一个节点入队然后在将其出队将其左右孩子入队。依

二叉树的建立及几种简单的遍历方法

#include "stdio.h" #include "stdlib.h" #define STACK_INIT_SIZE 100 //栈存储空间初始分配量 #define STACKINCREMENT 10 //存储空间分配增量 //------二叉树的存储结构表示------// typedef struct BiTNode{ int data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //-----顺序栈的存储结构表示------// typedef struct{ BiTree *top; BiTree *base; int stacksize; }SqStack; //*************************************************** //构造一个空栈s SqStack *InitStack(); //创建一颗二叉树 BiTree CreatBiTree(); //判断栈空 int StackEmpty(SqStack *S); //插入元素e为新的栈顶元素 void Push(SqStack *S,BiTree p); //若栈不为空,则删除s栈顶的元素e,将e插入到链表L中void Pop(SqStack *S,BiTree *q); //非递归先序遍历二叉树 void PreOrderTraverse(BiTree L); //非递归中序遍历二叉树 void InOrderTraverse(BiTree L); //非递归后序遍历二叉树 void PostOrderTraverse(BiTree L); //递归后序遍历二叉树 void PostOrder(BiTree bt); //递归中序遍历二叉树 void InOrder(BiTree bt); //递归先序遍历二叉树 void PreOrder(BiTree bt); //***************************************************

二叉树的建立及遍历

数据结构实验五 课程数据结构实验名称二叉树的建立及遍历第页 专业班级学号 姓名 实验日期:年月日评分 一、实验目的 1.学会实现二叉树结点结构和对二叉树的基本操作。 2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。 二、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。 2 .编写程序生成下面所示的二叉树,并采用先序遍历的非递归算法对此二叉 树进行遍历。 四、实验步骤 (描述实验步骤及中间的结果或现象。在实验中做了什么事情,怎么做的,发生的现象和中间结果) 第一题 #include "stdafx.h" #include"iostream.h" #include"stdlib.h"

#include"stdio.h" #includelchild); int n=depth(T->rchild); ?return (m>n?m:n)+1; } } //先序,中序建树 structnode*create(char *pre,char *ord,int n) { ?struct node*T; intm; T=NULL; ?if(n<=0) ?{ ?returnNULL; } ?else ?{ ?m=0; ??T=new(struct node); T->data=*pre; ?T->lchild=T->rchild=NULL; ?while(ord[m]!=*pre) ?m++; T->lchild=create(pre+1,ord,m); ?T->rchild=create(pre+m+1,ord+m+1,n-m-1);

二叉树的建立和遍历的实验报告doc

二叉树的建立和遍历的实验报告 篇一:二叉树的建立及遍历实验报告 实验三:二叉树的建立及遍历 【实验目的】 (1)掌握利用先序序列建立二叉树的二叉链表的过程。 (2)掌握二叉树的先序、中序和后序遍历算法。 【实验内容】 1. 编写程序,实现二叉树的建立,并实现先序、中序和后序遍历。 如:输入先序序列abc###de###,则建立如下图所示的二叉树。 并显示其先序序列为:abcde 中序序列为:cbaed 后序序列为:cbeda 【实验步骤】 1.打开VC++。 2.建立工程:点File->New,选Project标签,在列表中选Win32 Console Application,再在右边的框里为工程起好名字,选好路径,点OK->finish。至此工程建立完毕。 3.创建源文件或头文件:点File->New,选File标签,在列表里选C++ Source File。给文件起好名字,选好路径,点OK。至此一个源文件就被添加到了你刚创建的工程之中。

4.写好代码 5.编译->链接->调试 #include #include #define OK 1 #define OVERFLOW -2 typedef int Status; typedef char TElemType; typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; }BiTNode,*BiTree; Status CreateBiTree(BiTree &T) { TElemType ch; scanf("%c",&ch); if (ch=='#') T= NULL; else { if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))

数据结构实验报告-二叉树的实现与遍历

《数据结构》第六次实验报告 学生姓名 学生班级 学生学号 指导老师

一、实验内容 1) 采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序 以及按层次遍历的操作,求所有叶子及结点总数的操作。 2) 输出树的深度,最大元,最小元。 二、需求分析 遍历二叉树首先有三种方法,即先序遍历,中序遍历和后序遍历。 递归方法比较简单,首先获得结点指针如果指针不为空,且有左子,从左子递归到下一层,如果没有左子,从右子递归到下一层,如果指针为空,则结束一层递归调用。直到递归全部结束。 下面重点来讲述非递归方法: 首先介绍先序遍历: 先序遍历的顺序是根左右,也就是说先访问根结点然后访问其左子再然后访问其右子。具体算法实现如下:如果结点的指针不为空,结点指针入栈,输出相应结点的数据,同时指针指向其左子,如果结点的指针为空,表示左子树访问结束,栈顶结点指针出栈,指针指向其右子,对其右子树进行访问,如此循环,直至结点指针和栈均为空时,遍历结束。 再次介绍中序遍历: 中序遍历的顺序是左根右,中序遍历和先序遍历思想差不多,只是打印顺序稍有变化。具体实现算法如下:如果结点指针不为空,结点入栈,指针指向其左子,如果指针为空,表示左子树访问完成,则栈顶结点指针出栈,并输出相应结点的数据,同时指针指向其右子,对其右子树进行访问。如此循环直至结点指针和栈均为空,遍历结束。 最后介绍后序遍历: 后序遍历的顺序是左右根,后序遍历是比较难的一种,首先需要建立两个栈,一个用来存放结点的指针,另一个存放标志位,也是首先访问根结点,如果结点的指针不为空,根结点入栈,与之对应的标志位也随之入标志位栈,并赋值0,表示该结点的右子还没有访问,指针指向该结点的左子,如果结点指针为空,表示左子访问完成,父结点出栈,与之对应的标志位也随之出栈,如果相应的标志位值为0,表示右子树还没有访问,指针指向其右子,父结点再次入栈,与之对应的标志位也入栈,但要给标志位赋值为1,表示右子访问过。如果相应的标志位值为1,表示右子树已经访问完成,此时要输出相应结点的数据,同时将结点指针赋值为空,如此循环直至结点指针和栈均为空,遍历结束。 三、详细设计 源代码:

C++二叉树的创建与遍历实验报告

二叉树的创建与遍历 一、实验目的 1.学会实现二叉树结点结构和对二叉树的基本操作。 2.掌握对二叉树每种操作的具体实现,学会利用递归和非递归方法编写对二叉树这种递归数据结构进行处理的算法。 二、实验要求 1.认真阅读和掌握和本实验相关的教材内容。 2.编写完整程序完成下面的实验内容并上机运行。 3.整理并上交实验报告。 三、实验内容 1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归和非递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历。 四、实验步骤 源程序代码1 #include #include using namespace std; template struct BinTreeNode //二叉树结点类定义 { T data; //数据域 BinTreeNode *leftChild,*rightChild; //左子女、右子女域 BinTreeNode(T x=T(),BinTreeNode* l =NULL,BinTreeNode* r = NULL ) :data(x),leftChild(l),rightChild(r){} //可选择参数的默认构造函数 }; //------------------------------------------------------------------------- template void PreOrder_2(BinTreeNode *p) //非递归前序遍历 { stack * > S;

二叉树三种遍历算法代码_

二叉树三种遍历算法的源码 二叉树三种遍历算法的源码背诵版 本文给出二叉树先序、中序、后序三种遍历的非递归算法,此三个算法可视为标准算法,直接用于考研答题。 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize]; int top; }SqStack; void PreOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子树遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec 2.中序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize];

int top; }SqStack; void InOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子树遍历}//endif }//endwhile }//InOrderUnrec 3.后序遍历非递归算法 #define maxsize 100 typedef enum{L,R} tagtype; typedef struct { Bitree ptr; tagtype tag; }stacknode; typedef struct { stacknode Elem[maxsize]; int top; }SqStack; void PostOrderUnrec(Bitree t)

用C语言编写二叉树的建立与遍历

用C语言编写二叉树的建立与遍历 #include "stdio.h" #include "string.h" #define NULL 0 typedef struct BiTNode{ char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; BiTree Create(BiTree T){ char ch; ch=getchar(); if(ch=='#') T=NULL; else{ if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) printf("Error!"); T->data=ch; T->lchild=Create(T->lchild); T->rchild=Create(T->rchild); } return T;

} void Preorder(BiTree T){ if(T){ printf("%c",T->data); Preorder(T->lchild); Preorder(T->rchild); } } int Sumleaf(BiTree T){ int sum=0,m,n; if(T){ if((!T->lchild)&&(!T->rchild)) sum++; m=Sumleaf(T->lchild); sum+=m; n=Sumleaf(T->rchild); sum+=n; } return sum; } void zhongxu(BiTree T){ if(T){

zhongxu(T->lchild); printf("%c",T->data); zhongxu(T->rchild); } } void houxu(BiTree T){ if(T){ houxu(T->lchild); houxu(T->rchild); printf("%c",T->data); } } int Depth(BiTree T){ int dep=0,depl,depr; if(!T) dep=0; else{ depl=Depth(T->lchild); depr=Depth(T->rchild); dep=1+(depl>depr?depl:depr); } return dep; }

二叉树遍历课程设计心得【模版】

目录 一.选题背景 (1) 二.问题描述 (1) 三.概要设计 (2) 3.1.创建二叉树 (2) 3.2.二叉树的非递归前序遍历示意图 (2) 3.3.二叉树的非递归中序遍历示意图 (2) 3.4.二叉树的后序非递归遍历示意图 (3) 四.详细设计 (3) 4.1创建二叉树 (3) 4.2二叉树的非递归前序遍历算法 (3) 4.3二叉树的非递归中序遍历算法 (4) 4.4二叉树的非递归后序遍历算法 (5) 五.测试数据与分析 (6) 六.源代码 (6) 总结 (10) 参考文献: (11)

一.选题背景 二叉树的链式存储结构是用指针建立二叉树中结点之间的关系。二叉链存储结构的每个结点包含三个域,分别是数据域,左孩子指针域,右孩子指针域。因此每个结点为 由二叉树的定义知可把其遍历设计成递归算法。共有前序遍历、中序遍历、后序遍历。可先用这三种遍历输出二叉树的结点。 然而所有递归算法都可以借助堆栈转换成为非递归算法。以前序遍历为例,它要求首先要访问根节点,然后前序遍历左子树和前序遍历右子树。特点在于所有未被访问的节点中,最后访问结点的左子树的根结点将最先被访问,这与堆栈的特点相吻合。因此可借助堆栈实现二叉树的非递归遍历。将输出结果与递归结果比较来检验正确性。。 二.问题描述 对任意给定的二叉树(顶点数自定)建立它的二叉链表存贮结构,并利用栈的五种基本运算(置空栈、进栈、出栈、取栈顶元素、判栈空)实现二叉树的先序、中序、后序三种遍历,输出三种遍历的结果。画出搜索顺序示意图。

三.概要设计 3.1.创建二叉树 3.2.二叉树的非递归前序遍历示意图 图3.2二叉树前序遍历示意图3.3.二叉树的非递归中序遍历示意图 图3.3二叉树中序遍历示意图

用递归和非递归算法实现二叉树的三种遍历

○A ○C ○D ○B ○E○F G 《数据结构与算法》实验报告三 ——二叉树的操作与应用 一.实验目的 熟悉二叉链表存储结构的特征,掌握二叉树遍历操作及其应用 二. 实验要求(题目) 说明:以下题目中(一)为全体必做,(二)(三)任选其一完成 (一)从键盘输入二叉树的扩展先序遍历序列,建立二叉树的二叉链表存储结构;(二)分别用递归和非递归算法实现二叉树的三种遍历; (三)模拟WindowsXP资源管理器中的目录管理方式,模拟实际创建目录结构,并以二叉链表形式存储,按照凹入表形式打印目录结构(以扩展先序遍历序列输入建立二叉链表结构),如下图所示: (基本要求:限定目录名为单字符;扩展:允许目录名是多字符组合) 三. 分工说明 一起编写、探讨流程图,根据流程图分工编写算法,共同讨论修改,最后上机调试修改。 四. 概要设计 实现算法,需要链表的抽象数据类型: ADT Binarytree { 数据对象:D是具有相同特性的数据元素的集合 数据关系R: 若D为空集,则R为空集,称binarytree为空二叉树;

若D不为空集,则R为{H},H是如下二元关系; (1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱; (2)若D-{root}不为空,则存在D-{root}={D1,Dr},且D1∩Dr为空集; (3)若D1不为空,则D1中存在唯一的元素x1,∈H,且存在D1上的关系H1是H的子集;若Dr不为空集,则Dr中存在唯一的元素 Xr,∈H,且存在Dr上的关系Hr为H的子集;H={,,H1,Hr}; (4) (D1,{H1})是一颗符合本定义的二叉树,称为根的左子树,(Dr,{Hr}) 是一颗符合本定义的二叉树,称为根的右子树。 基本操作: Creatbitree(&S,definition) 初始条件:definition给出二叉树S的定义 操作结果:按definition构造二叉树S counter(T) 初始条件:二叉树T已经存在 操作结果:返回二叉树的总的结点数 onecount(T) 初始条件:二叉树T已经存在 操作结果:返回二叉树单分支的节点数 Clearbintree(S) 初始条件:二叉树S已经存在 操作结果:将二叉树S清为空树 Bitreeempty(S) 初始条件:二叉树S已经存在 操作结果:若S为空二叉树,则返回TRUE,否则返回FALSE Bitreedepth(S,&e) 初始条件:二叉树S已经存在 操作结果:返回S的深度 Parent(S) 初始条件:二叉树S已经存在,e是S中的某个结点 操作结果:若e是T的非根结点,则返回它的双亲,否则返回空Preordertraverse(S) 初始条件:二叉树S已经存在,Visit是对结点操作的应用函数。 操作结果:先序遍历S,对每个结点调用函数visit一次且仅一次。 一旦visit失败,则操作失败。 Inordertraverse (S,&e) 初始条件:二叉树S已经存在,Visit是对结点操作的应用函数。

二叉树的随机生成及其遍历

二叉树的随机生成及其遍历 张zhaohan 10804XXXXX 2010/6/12 问题重述 利用随机函数产生50个(不大于100且各不相同的)随机整数,用这些整数来生成一棵二叉树,分别对二叉树进行先根遍历,中根遍历和后根遍历并输出树中结点元素序列。 程序设计 (一)需求分析: ●问题的定义与要求:1、产生50个不大于100且各不相同的随机整数(由系统的随机函数生成并对100取模);2、先根遍历并输出结果;3、中根遍历并输出结果;4、后根遍历并输出结果;5、按层次浏览二叉树结点;6、退出程序。 ●输入:所需功能,选项为1~6。 ●输出:按照用户功能选择输出结果。 ●限制:输入的功能选择在1~6之间,否则无回应。 ●模块功能及要求: RandDif():生成50个随机不大于100的整数,每次生成不同随机整数。 CreateBitree():给数据结点生成二叉树,使每个结点的左右儿子指针指向左右儿子。NRPreOrder():非递归算法的先根遍历。 inOrderTraverse():递归算法的中根遍历。 PostOrderTraverse():递归算法的后根遍历。 Welcome():欢迎窗口。 Menu():菜单。 Goodbye():再见窗口。 (二)概要设计:

首先要生成二叉树,由于是对随机生成的50个数生成二叉树,故可以采取顺序存储的方式,对结点的左右儿子进行赋值。生成的二叉树是完全二叉树。 先根遍历的非递归算法: 1、根结点进栈 2、结点出栈,被访问 3、结点的右、左儿子(非空)进栈 4、反复执行2、3 ,至栈空为止。 先根遍历的算法流程图: 根结点进栈(a[0]=T->boot,p=a[0]) 访问结点printf(*p) 右儿子存在则进栈a[i]=(*p).rchild; i++; 左儿子存在则进栈a[i]=(*p).rchild; i++; 栈顶降低top--:i--;p=a[i]; 栈非空while(i>-1) 返回 中根遍历的递归算法流程图: T为空 Y N Return; inOrderTraverse(T->lchild) Printf(T->data) inOrderTraverse(T->rchild)

相关文档
最新文档