遍历二叉树(递归+非递归)实验报告

合集下载

201184601120 杨麒 二叉树遍历实验报告

201184601120 杨麒 二叉树遍历实验报告

数据结构(双语)——项目文档报告用递归、非递归两种方法遍历二叉树专业:计算机科学与技术班级:11接计指导教师:苏亚光姓名:杨麒学号:201184601120目录一、设计思想 (2)二、算法流程图 (3)三、源代码 (6)四、运行结果 (10)五、遇到的问题及解决 (10)六、心得体会 (11)一、设计思想递归实现二叉树遍历的思想:1.递归遍历二叉树的前提是有一个二叉树,所以应该先创建一个二叉树,用先序递归的方式创建的二叉树。

2.中序递归遍历二叉树的思想是先访问左子树,然后访问根节点,最后访问右子树。

当访问左子树或是右子树的时候,实际上调用的是函数本身。

在这里就体现了递归的思想,当函数的返回值是0的时候,则返回上一次的程序,继续执行下面的语句。

3.先序递归遍历二叉树的思想是先访问根节点,然后访问左子树,最后访问右子树。

同样如步骤3的方式相同,当访问左子树或者是右子树的收,实际上调用的是函数本身,直到返回值是0的时候,返回上一层的程序继续执行。

4.后序递归遍历二叉树的思想是先访问左子树,然后访问右子树,最后访问根节点。

同样跟步骤3的方式相同,当访问左子树或者右子树的时候实际上是调用的是方法本直到有返回值的时候才返回上一层的程序,继续执行.非递归实现二叉树遍历的思想:1.跟递归遍历二叉树的前提一样,首先应该创建一个二叉树,同样使用先序递归的方式创建二叉树。

2.中序非递归遍历二叉树的思想是遍历左子树,访问根节点,遍历右子树。

当遍历左子树时,算法要依据节点的左孩子Lchild的指示进入左子树去进行遍历,在每一次向左子树前进时进入数组,从最左边的开始访问,并访问当前结点的父节点,这时如果父节点的Rchild非空,就将它同时放入数组与比较数组,于是数组保存的是一系列的根节点,并与比较数组比较,防止重复打印,每次一个父节点的访问同时进行数组边界的减一操作,直到数组为空时则二叉树的中序遍历操作结束。

3.先序非递归遍历二叉树的思想是首先访问根节点,遍历左子树,遍历右子树。

【二叉树的建立和遍历实验报告】二叉树的遍历实验心得

【二叉树的建立和遍历实验报告】二叉树的遍历实验心得

【二叉树的建立和遍历实验报告】二叉树的遍历实验心得[题目] 建立二叉树并求指定结点路径、深度、叶子个数和左右子树交换。

[问题描述]要求能够按先序遍历次序输入二叉树中结点的值来构造二叉树T;然后用递归和非递归算法实现二叉树T 的中序遍历;接着编写算法实现求二叉树T中指定结点的路径,即从键盘输入二叉树T 的任一结点,可以输出从根结点到该结点所经历的结点;最后编写二叉树的三个应用算法(求二叉树的深度、求二叉树的叶子结点个数、将二叉树左右子树交换)。

[基本要求]分别建立二叉树存储结构的输入输出函数、输出中序遍历函数、指定节点路径函数、求深度函数、求叶子个数函数和将二叉树左右子树交换函数一、需求与规格说明1、定义二叉树的存储结构,每个结点中设置三个域,即值域、左指针域、右指针域。

要建立二叉树T的链式存储结构,即建立二叉链表。

根据输入二叉树结点的形式不同,建立的方法也不同,本系统采用先序序列递归建立二叉树,建立如下图所示的二叉树。

应该在程序运行窗口的主控菜单后,先选择“1”并回车,紧接着在程序运行窗口中提示信息“输入二叉树的先序序列结点值:”之后,采用以下字符序列:abc@@de@g@@f@@@ (以@替代空格,但是程序中直接输入空格就是,详细见代码注释)作为建立二叉树T的输入字符序列并回车,窗口出现:二叉树的链式存储结构建立完成!图1 二叉树的图形结构2、二叉树的遍历。

本系统采用非递归中序遍历算法进行中序遍历,这意味着遍历右子树时不再需要保存当前层的根指针,可直接修改栈顶记录中的指针即可。

需要在程序运行窗口的主控菜单中选择“2”并回车,程序运行窗口会出现以下中序遍历序列:该二叉树的中序遍历序列是: cbegdfa3、求二叉树的指定结点路径。

在程序运行窗口的主控菜单中选择“3”并回车,在程序运行窗口中提示信息“输入要求路径的结点值:”输入“g”并回车,会得到结果为:→a→b→d→e→g如果输入“i”并回车,会得到结果为:没有要求的结点!4、求二叉树的深度。

二叉树的遍历实验报告

二叉树的遍历实验报告

二叉树的遍历实验报告二叉树的遍历实验报告引言:二叉树是一种常见的数据结构,它由节点和连接节点的边组成。

在实际应用中,我们经常需要对二叉树进行遍历,以便对其中的节点进行访问和操作。

本次实验旨在探索二叉树的遍历算法,并通过实验验证其正确性和效率。

一、二叉树的定义和基本操作二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。

根据节点的访问顺序,二叉树的遍历可以分为前序遍历、中序遍历和后序遍历三种方式。

前序遍历是指先访问根节点,然后按照左子树、右子树的顺序递归地进行遍历;中序遍历是指先按照左子树、根节点、右子树的顺序递归地进行遍历;后序遍历是指先按照左子树、右子树、根节点的顺序递归地进行遍历。

二、实验设计和方法为了验证二叉树的遍历算法的正确性和效率,我们设计了以下实验方案:1. 构建二叉树:我们首先构建一个具有一定规模的二叉树,以模拟实际应用中的情况。

为了方便起见,我们选择随机生成一棵二叉树,并确保其结构合理。

2. 实现遍历算法:我们根据前文所述的遍历方式,实现了相应的遍历算法。

在实现过程中,我们考虑到了递归和迭代两种方式,并分别进行了实验比较。

3. 遍历实验:我们使用不同规模的二叉树进行遍历实验,并记录遍历的结果和所花费的时间。

通过对比不同规模下不同遍历方式的结果和时间,我们可以评估遍历算法的效率和准确性。

三、实验结果和分析在实验中,我们构建了一棵具有1000个节点的二叉树,并分别使用前序、中序和后序遍历算法进行遍历。

通过实验结果的比较,我们得出以下结论:1. 遍历结果的正确性:无论是前序、中序还是后序遍历,我们都能够正确地访问到二叉树中的每个节点。

这表明我们所实现的遍历算法是正确的。

2. 遍历算法的效率:在1000个节点的二叉树中,我们发现中序遍历算法的执行时间最短,后序遍历算法的执行时间最长,前序遍历算法的执行时间居中。

这是因为中序遍历算法在访问节点时可以尽可能地减少递归次数,而后序遍历算法需要递归到最深层才能返回。

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

二叉树的建立和遍历的实验报告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 -2typedef 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))))return OVERFLOW;T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); }return OK;} // CreateBiTreevoid PreOrder(BiTree T) {if(T){printf("%c",T->data); PreOrder(T->lchild); PreOrder(T->rchild);}}void InOrder(BiTree T) {if(T){InOrder(T->lchild);printf("%c",T->data);InOrder(T->rchild);}}void PostOrder(BiTree T){if(T){PostOrder(T->lchild); PostOrder(T->rchild);printf("%c",T->data);}}void main(){BiTree T;CreateBiTree(T);printf("\n先序遍历序列:"); PreOrder(T);printf("\n中序遍历序列:"); InOrder(T);printf("\n后序遍历序列:"); PostOrder(T);}【实验心得】这次实验主要是通过先序序列建立二叉树,和二叉树的先序、中序、后续遍历算法。

二叉树的遍历算法实验报告

二叉树的遍历算法实验报告

二叉树的遍历算法实验报告二叉树的遍历算法实验报告引言:二叉树是计算机科学中常用的数据结构之一,它是由节点组成的层次结构,每个节点最多有两个子节点。

在实际应用中,对二叉树进行遍历是一项重要的操作,可以帮助我们理解树的结构和节点之间的关系。

本文将介绍二叉树的三种遍历算法:前序遍历、中序遍历和后序遍历,并通过实验验证其正确性和效率。

一、前序遍历前序遍历是指先访问根节点,然后按照先左后右的顺序遍历左右子树。

具体的实现可以通过递归或者使用栈来实现。

我们以递归方式实现前序遍历算法,并进行实验验证。

实验步骤:1. 创建一个二叉树,并手动构造一些节点和它们之间的关系。

2. 实现前序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先访问当前节点,然后递归调用函数遍历左子树,最后递归调用函数遍历右子树。

4. 调用前序遍历函数,输出遍历结果。

实验结果:经过实验,我们得到了正确的前序遍历结果。

这证明了前序遍历算法的正确性。

二、中序遍历中序遍历是指按照先左后根再右的顺序遍历二叉树。

同样,我们可以使用递归或者栈来实现中序遍历算法。

在本实验中,我们选择使用递归方式来实现。

实验步骤:1. 继续使用前面创建的二叉树。

2. 实现中序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先递归调用函数遍历左子树,然后访问当前节点,最后递归调用函数遍历右子树。

4. 调用中序遍历函数,输出遍历结果。

实验结果:通过实验,我们得到了正确的中序遍历结果。

这证明了中序遍历算法的正确性。

三、后序遍历后序遍历是指按照先左后右再根的顺序遍历二叉树。

同样,我们可以使用递归或者栈来实现后序遍历算法。

在本实验中,我们选择使用递归方式来实现。

实验步骤:1. 继续使用前面创建的二叉树。

2. 实现后序遍历算法的递归函数,函数的输入为根节点。

3. 在递归函数中,首先递归调用函数遍历左子树,然后递归调用函数遍历右子树,最后访问当前节点。

4. 调用后序遍历函数,输出遍历结果。

二叉树遍历的实习报告

二叉树遍历的实习报告

实习报告实习内容:二叉树遍历实习时间:2023实习单位:某高校计算机实验室一、实习目的本次实习的主要目的是通过实现二叉树的遍历,加深对二叉树数据结构的理解,掌握二叉树的常见操作,提高编程能力。

二、实习内容1. 理解二叉树的基本概念和性质,包括节点之间的关系、树的深度、高度等。

2. 掌握二叉树的存储结构,包括顺序存储和链式存储。

3. 实现二叉树的前序遍历、中序遍历和后序遍历。

4. 通过实际编程,验证二叉树遍历的正确性。

三、实习过程1. 二叉树的基本概念和性质:二叉树是一种非线性的数据结构,每个节点最多有两个子节点。

节点之间的关系包括父子关系、兄弟关系等。

树的深度是指从根节点到最远叶子节点的最长路径上的边数,高度是指从根节点到最远叶子节点的最长路径上的边数加1。

2. 二叉树的存储结构:二叉树可以用顺序存储结构或链式存储结构表示。

顺序存储结构使用数组来实现,每个节点存储在数组的一个位置中,节点之间的父子关系通过数组下标来表示。

链式存储结构使用链表来实现,每个节点包含数据域和两个指针域,分别指向左子节点和右子节点。

3. 二叉树的遍历:二叉树的遍历是指按照一定的顺序访问树中的所有节点。

常见的遍历方式有前序遍历、中序遍历和后序遍历。

前序遍历是指先访问根节点,然后递归遍历左子树,最后递归遍历右子树。

中序遍历是指先递归遍历左子树,然后访问根节点,最后递归遍历右子树。

后序遍历是指先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

4. 编程实现:根据二叉树的存储结构和遍历方法,编写C语言程序实现二叉树的前序遍历、中序遍历和后序遍历。

程序中使用递归函数来实现遍历操作,通过建立链式存储结构,验证遍历的正确性。

四、实习心得通过本次实习,我对二叉树的数据结构有了更深入的了解,掌握了二叉树的存储方式和常见操作。

在实现二叉树遍历的过程中,我学会了如何使用递归函数解决问题,提高了编程能力。

同时,通过实际编程验证了二叉树遍历的正确性,增强了对算法理解的信心。

二叉树遍历实验报告

二叉树遍历实验报告

1.实验题目二叉树的建立与遍历[问题描述]建立一棵二叉树,并对其进行遍历(先序、中序、后序),打印输出遍历结果。

2.需求分析(1)输入的形式和输入值的范围:以字符形式按先序遍历输入(2)输出的形式:依次按递归先序、中序、后序遍历,非递归先序、中序、后序遍历结果输出(3) 程序所能达到的功能:从键盘接受输入(先序)进行遍历(先序、中序、后序),将遍历结果打印输。

(4) 测试数据:ABCффDEфGффFффф(其中ф表示空格字符)则输出结果为先序:ABCDEGF中序:CBEGDFA后序:CGBFDBA3.概要设计(1)struct btnode{char data; 数据struct btnode *Lchild;左子数指针struct btnode *Rchild; 右子数指针};struct btnode *createbt(struct btnode *bt )初始条件:空二叉树存在操作结果:先序建立二叉树void preOrder(struct btnode *bt)初始条件:二叉树存在递归先序遍历二叉树void preOrder1(struct btnode *bt)初始条件:二叉树存在操作结果:非递归先序遍历void midOrder(struct btnode *bt)初始条件:二叉树存在操作结果:递归中序遍历void midOrder1(struct btnode *bt)初始条件:二叉树存在操作结果:非递归中序遍历void postOrder(struct btnode *bt)初始条件:二叉树存在操作结果:递归后序遍历void postOrder1 (struct btnode *bt)初始条件:二叉树存在操作结果:非递归后序遍历void main() 主函数(2)void main() 主函数{*createbtpreOrderpreOrder1midOrdermidOrder1postOrderpostOrder1}4.详细设计struct btnode{char data;struct btnode *Lchild;struct btnode *Rchild;};struct btnode *createbt(struct btnode *bt ){ 输入结点数据c检查存储空间将c赋给结点参数p递归建立左子树递归建立右子树}void preOrder(struct btnode *bt){判断树是否为空输出根结点数data递归遍历左子树递归遍历右子树}void preOrder1(struct btnode *bt){定义栈,结点参数pWhile(栈或p是否为空){While(p!=null){输出根结点数data将根结点压栈遍历左子树}提取栈顶元素值栈顶元素出栈访问右子树}void midOrder(struct btnode *bt){判断树是否为空递归遍历左子树输出根结点数data递归遍历右子树}void midOrder1(struct btnode *bt){定义栈,结点参数pWhile(栈或p是否为空){While(p!=null){将根结点压栈遍历左子树}提取栈顶元素值输出根结点数data栈顶元素出栈访问右子树}void postOrder(struct btnode *bt){判断树是否为空递归遍历左子树递归遍历右子树输出根结点数data}void postOrder1 (struct btnode *bt){定义栈,结点参数p,prebt入栈While(栈或p是否为空){提取栈顶元素值if判断p是否为空或是pre的根结点输出根结点数data栈顶元素出栈栈顶元素p赋给pre记录else if右结点非空将右结点压栈if左结点将左结点压栈}}void main(){struct btnode *root=NULL;root=createbt(root);preOrder(root); midOrder(root); postOrder(root);preOrder1(root); midOrder1(root);postOrder1(root);}5.调试分析(1)先序建立二叉树时,虽用到递归建左右子树,但没有把他们赋值给根节点的左右指针,造成二叉树脱节。

树的遍历实验报告

树的遍历实验报告

实验项目:树的遍历1.实验目的:学会创建一棵二叉树,以及完成对树的简单操作。

2.实验内容:1)生成一棵以二叉链表存储的二叉树bt(不少于15个结点)2)分别用递归和非递归方法前序遍历bt,并以缩格形式打印bt 上各结点的信息。

3)编写算法,交换bt上所有结点的左、右子树,并以缩格形式打印出交换前后的bt结点信息。

3.程序简介:先创建一棵二叉树,递归非递归前序遍历,层次遍历,交换左右子树,缩格打印各结点的信息。

4.算法设计介绍:首先按照前序遍历的顺序递归创建一棵二叉树,然后序遍历的非递归使用堆栈完成的,即访问该结点的时候,如果有右孩子,让右孩子进栈,访问左孩子,当左孩子为空时,抛出栈顶的元素,访问出栈的这个元素的左右孩子。

缩格打印和层次遍历想法类似,都是借助队列完成的,把当前结点的左右孩子进队列之后,让这个结点出队列。

交换左右子树,就是当某个结点的左右子树不同时为空时,定义一个中间变量交换。

5.困难及解答一开始创建二叉树的参数我想用指向结构体的指针,后来才意识到得用指向指针的指针,想了好一段时间才想明白,因为某个结点的左右孩子是指向结点的指针,要想再指向一个指针,只能用指针的指针了。

6.心得树这一章我听得乱七八糟,上课能听懂,但就是不会编程,要不是书上有算法,我估计我肯定编不出来,看来还是得多编啊。

程序清单/*// 我真诚地保证:// 我独立完成了整个程序从分析、设计到编码的所有工作。

// 如果在上述过程中,我遇到了什么困难而求教于人,那么,我将在程序实习报告中// 详细地列举我所遇到的问题,以及别人给我的提示。

// 我的程序里中凡是引用到其他程序或文档之处,// 例如教材、课堂笔记、网上的源代码以及其他参考书上的代码段,// 我都已经在程序的注释里很清楚地注明了引用的出处。

// 我从未没抄袭过别人的程序,也没有盗用别人的程序,// 不管是修改式的抄袭还是原封不动的抄袭。

// 我编写这个程序,从来没有想过要去破坏或妨碍其他计算机系统的正常运转。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告
运行结果:
递归算法:非递归算法:
实验总结(结论或问题分析):
通过实验,加深了对C语言尤其是函数调用部分的认识和掌握。

没有找到在实验运行结果上明确区分递归算法实现的遍历和非递归算法实现的遍历的方法。

实验成绩任课教师签名红霞
附:源程序:
递归算法程序
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxsize 100
#define FALSE 0
#define TRUE 1
typedef struct node //二叉树结构体类型定义
{
char data;
struct node *lchild;
struct node *rchild;
}bitnode,*bitree;
/*扩展先序序列创建二叉链表*/
void cteatebitree(bitree *bt)
{
char ch;
ch=getchar();
if(ch=='.')*bt=NULL;
else
{
*bt=(bitree)malloc(sizeof(bitnode));
(*bt)->data=ch;
cteatebitree(&((*bt)->lchild));
cteatebitree(&((*bt)->rchild));
}
}
/*先序递归遍历*/
void preorder(bitree root)
{
if(root!=NULL)
{
printf("%c ",root->data);
preorder(root->lchild);
preorder(root->rchild);
}
}
/*中序递归遍历*/
void inorder(bitree root)
{
if(root!=NULL)
{
preorder(root->lchild);
printf("%c ",root->data);
preorder(root->rchild);
}
}
/*后序递归遍历*/
void postorder(bitree root)
{
if(root!=NULL)
{
preorder(root->lchild);
preorder(root->rchild);
printf("%c ",root->data);
}
}
void main()
{
bitree bt;
cteatebitree(&bt);
printf("先序递归遍历序列:\n");
preorder(bt);
printf("\n");
printf("中序递归遍历序列:\n");
inorder(bt);
printf("\n");
printf("后序递归遍历序列:\n");
postorder(bt);
printf("\n");
}
非递归算法程序
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define FALSE 0
#define TRUE 1
#define maxsize 100
typedef struct node //二叉树结构体定义{
char data;
struct node *lchild;
struct node *rchild;
}bitnode,*bitree;
typedef struct //顺序栈结构体定义{
bitree elem[maxsize];
int top;
}seqstack;
int push(seqstack *s,bitree x) //入栈
{
if(s->top==maxsize-1)
return(FALSE);
s->top++;
s->elem[s->top]=x;
return(TRUE);
}
bitree pop(seqstack *s,bitree x) //出栈
{
if(s->top==-1) return NULL;
else
{
x=s->elem[s->top];
s->top--;
return x;
}
}
int gettop(seqstack *s,bitree *x) //读取栈顶元素
{
if(s->top==-1) return FALSE;
else
{
*x=s->elem[s->top];
return TRUE;
}
}
void createbitree(bitree *bt) //扩展先序序列创建二叉链表{
char ch;
ch=getchar();
if(ch=='.')*bt=NULL;
else
{
*bt=(bitree)malloc(sizeof(bitnode));
(*bt)->data=ch;
createbitree(&((*bt)->lchild));
createbitree(&((*bt)->rchild));
}
}
void preorder1(bitree root,seqstack s) //先序遍历{
bitnode *p;
p=root;
while(p!=NULL||!(s.top==-1))
{
while(p!=NULL)
{
printf("%c",p->data);
push(&s,p);
p=p->lchild;
}
if(!(s.top==-1))
{
p=pop(&s,p);
p=p->rchild;
}
}
}
void inorder1(bitree root,seqstack s) //中序遍历{
bitnode *p;
s.top=-1;
p=root;
while(p!=NULL||!(s.top==-1))
{
if(p!=NULL)
{
push(&s,p);
p=p->lchild;
else
{
p=pop(&s,p);
printf("%c",p->data);
p=p->rchild;
}
}
}
void postorder1(bitree root) //后序遍历{
bitnode *p,*q;
seqstack s;
q=NULL;
p=root;
s.top=-1;
//printf("%c",p->data);
while(p!=NULL||!(s.top==-1))
{while(p!=NULL)
{
push(&s,p); p=p->lchild;
}
if(!(s.top==-1))
{
gettop(&s,&p);
if((p->rchild==NULL)||(p->rchild==q))
{
printf("%c",p->data);
q=p;
p=pop(&s,p);
p=NULL;
else p=p->rchild;
}
}
}
void main()
{
printf("先序序列创建二叉树\n");
seqstack s;
s.top=-1;
bitree root;
createbitree(&root);
printf("先序遍历序列:\n");
preorder1(root,s);
printf("\n");
printf("中序遍历序列:\n");
inorder1(root,s);
printf("\n");
printf("后序遍历序列:\n");
postorder1(root);
printf("\n");
}。

相关文档
最新文档