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

合集下载

数据结构二叉树遍历实验报告

数据结构二叉树遍历实验报告

数据结构二叉树遍历实验报告数据结构二叉树遍历实验报告一、引言本文档旨在详细介绍二叉树遍历的实验过程和结果。

二叉树是一种在计算机科学领域常用的数据结构,通过遍历二叉树可以获取树中的所有节点数据。

本实验将分别介绍前序遍历、中序遍历和后序遍历这三种常见的遍历方法。

二、实验目的本实验的目的是通过实际操作,加深对二叉树遍历方法的理解,并验证这些遍历方法的正确性和效率。

三、实验环境本实验使用的环境如下:●操作系统: Windows 10●开发工具: Visual Studio Code●编程语言: C++四、实验步骤1.创建二叉树数据结构1.1 定义二叉树节点的结构,包含数据和左右子节点指针。

1.2 创建一个二叉树类,包含插入节点、删除节点、查找节点等方法。

1.3 使用已有的数据集构建二叉树,确保树的结构合理。

2.前序遍历前序遍历是先访问根节点,然后递归地遍历左子树和右子树。

2.1 以递归方式实现前序遍历。

2.2 以迭代方式实现前序遍历。

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

3.1 以递归方式实现中序遍历。

3.2 以迭代方式实现中序遍历。

4.后序遍历后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点。

4.1 以递归方式实现后序遍历。

4.2 以迭代方式实现后序遍历。

五、实验结果1.前序遍历结果:[节点1数据] [节点2数据] [节点4数据] [节点5数据] [节点3数据]2.中序遍历结果:[节点4数据] [节点2数据] [节点5数据] [节点1数据] [节点3数据]3.后序遍历结果:[节点4数据] [节点5数据] [节点2数据] [节点3数据] [节点1数据]六、实验分析通过实验结果可以看出,不同的遍历顺序得到的节点顺序也不同。

前序遍历先访问根节点,中序遍历先遍历左子树,后序遍历先遍历右子树。

根据需要,可以选择合适的遍历方法来处理二叉树的节点数据。

七、结论本实验验证了前序遍历、中序遍历和后序遍历的正确性,并且对比了它们的不同。

数据结构实验报告 二叉树

数据结构实验报告 二叉树

数据结构实验报告二叉树数据结构实验报告:二叉树引言:数据结构是计算机科学中的重要基础,它为我们提供了存储和组织数据的方式。

二叉树作为一种常见的数据结构,广泛应用于各个领域。

本次实验旨在通过实践,深入理解二叉树的概念、性质和操作。

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

二叉树可以为空树,也可以是由根节点和左右子树组成的非空树。

1.2 基本性质(1)每个节点最多有两个子节点;(2)左子树和右子树是有顺序的,不能颠倒;(3)二叉树的子树仍然是二叉树。

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

在实际应用中,前序遍历常用于复制一颗二叉树或创建二叉树的副本。

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

中序遍历的结果是一个有序序列,因此在二叉搜索树中特别有用。

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

后序遍历常用于计算二叉树的表达式或释放二叉树的内存。

三、二叉树的实现与应用3.1 二叉树的存储结构二叉树的存储可以使用链式存储或顺序存储。

链式存储使用节点指针连接各个节点,而顺序存储则使用数组来表示二叉树。

3.2 二叉树的应用(1)二叉搜索树:二叉搜索树是一种特殊的二叉树,它的左子树上的节点都小于根节点,右子树上的节点都大于根节点。

二叉搜索树常用于实现查找、插入和删除等操作。

(2)堆:堆是一种特殊的二叉树,它满足堆序性质。

堆常用于实现优先队列,如操作系统中的进程调度。

(3)哈夫曼树:哈夫曼树是一种带权路径最短的二叉树,常用于数据压缩和编码。

四、实验结果与总结通过本次实验,我成功实现了二叉树的基本操作,包括创建二叉树、遍历二叉树和查找节点等。

在实践中,我进一步理解了二叉树的定义、性质和应用。

二叉树作为一种重要的数据结构,在计算机科学中有着广泛的应用,对于提高算法效率和解决实际问题具有重要意义。

二叉树的建立和遍历的实验报告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);}【实验心得】这次实验主要是通过先序序列建立二叉树,和二叉树的先序、中序、后续遍历算法。

二叉树遍历的实习报告

二叉树遍历的实习报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

二叉树的遍历实验报告

二叉树的遍历实验报告

二叉树的遍历实验报告实验报告:二叉树的遍历(先序遍历、中序遍历、后序遍历)一、引言二叉树是一种非常常见的数据结构,在计算机领域有着广泛的应用。

对二叉树进行遍历操作是其中最基本的操作之一、本实验旨在通过对二叉树的先序遍历、中序遍历和后序遍历的实践,加深对二叉树遍历算法的理解和掌握。

二、目的1.掌握二叉树先序遍历的算法原理和实现方法;2.掌握二叉树中序遍历的算法原理和实现方法;3.掌握二叉树后序遍历的算法原理和实现方法;4.使用递归和非递归两种方式实现以上三种遍历算法;5.进行正确性验证和性能评估。

三、方法1.算法原理:1.1先序遍历:先访问根节点,然后递归遍历左子树,再递归遍历右子树;1.2中序遍历:先递归遍历左子树,然后访问根节点,最后递归遍历右子树;1.3后序遍历:先递归遍历左子树,再递归遍历右子树,最后访问根节点。

2.实现方法:2.1递归实现:采用函数递归调用的方式,实现对二叉树的遍历;2.2非递归实现:采用栈的数据结构,模拟递归的过程,实现对二叉树的遍历。

四、实验步骤1.数据结构设计:1.1定义二叉树的节点结构,包括节点值和两个指针(分别指向左子节点和右子节点);1.2定义一个栈结构,用于非递归实现时的辅助存储。

2.先序遍历:2.1递归实现:按照先序遍历的原理,通过递归调用遍历左子树和右子树,再输出根节点;2.2非递归实现:通过栈结构模拟递归的过程,先将根节点入栈,然后循环将栈顶节点弹出并输出,再将其右子节点入栈,最后将左子节点入栈,直到栈为空。

3.中序遍历:3.1递归实现:按照中序遍历的原理,通过递归调用先遍历左子树,再输出根节点,最后遍历右子树;3.2非递归实现:先将根节点入栈,然后循环将左子节点入栈,直到左子节点为空,然后弹出栈顶节点并输出,再将其右子节点入栈,重复以上过程直到栈为空。

4.后序遍历:4.1递归实现:按照后序遍历的原理,通过递归调用先遍历左子树,再遍历右子树,最后输出根节点;4.2非递归实现:通过栈结构模拟递归的过程,先将根节点入栈,然后重复以下步骤直到栈为空。

数据结构实验报告二叉树

数据结构实验报告二叉树
return s;
}
void dispbtnode1(btnode *b)
{
btnode *st[maxsize],*p;
int level[maxsize][2],top=-1,n,i,width=4;
char type;
if(b!=NULL)
{
top++;
st[top]=b;
level[top][0]=width;
level[top][0]=n+width;
level[top][1]=1;
}
if(p->lchild!=NULL)
{
top++;
st[top]=p->lchild;
level[top][0]=n+width;
level[top][1]=0;
}
}
}
}
2)先序,中序、后序遍历功能实现,因为想自己更能读懂理解程序,没有使用递归算法。
}
btnode *rchildnode(btnode *p)
{
return p->rchild ;
}
btnode * revers(btnode *b)//交换左右子树
{
if(b!=NULL)
{
if(b->rchild !=NULL||b->lchild !=NULL)
{
btn;lchild );
(3)根据二叉树的基本运算,设计先序遍历和中序遍历(或者中序遍历和后序遍历),确定二叉树的算法。
(4)在不改变原有二叉树结构的条件下,将二叉树左右孩子进行交换,并采用凹入表示法和括号表示法输出原有二叉树及交换子树后的二叉树。

二叉树递归遍历数据结构实验报告

二叉树递归遍历数据结构实验报告

二叉树递归遍历数据结构实验报告一、引言二叉树是一种简单而重要的树形结构,在计算机科学领域中被广泛应用。

它具有良好的动态性能和数据组织能力,递归遍历是二叉树最基本的操作之一、本次实验旨在通过编程实现二叉树的递归遍历算法,并对实验结果进行分析和总结。

二、实验目的1.掌握二叉树的基本概念和操作方法;2.熟悉递归算法的实现过程;3.实践二叉树的递归遍历算法。

三、实验原理1.二叉树的概念二叉树是一种树形结构,其中每个节点最多有两个子节点,被分为左子树和右子树。

树中每个节点最多有一个父节点,除了根节点没有父节点。

二叉树的递归定义:(1)空树是一个二叉树;(2)一棵非空二叉树由根节点和左子树、右子树组成。

2.二叉树的递归遍历二叉树的遍历方式分为三种:前序遍历、中序遍历和后序遍历。

其定义如下:(1)前序遍历:根节点->左子树->右子树;(2)中序遍历:左子树->根节点->右子树;(3)后序遍历:左子树->右子树->根节点。

四、实验过程1.定义二叉树的数据结构和相关操作方法首先,我们需要定义二叉树的节点结构,包含数据域和左右子节点指针域。

然后,可定义插入节点、删除节点等操作方法。

2.实现递归遍历算法(1)前序遍历前序遍历的流程为:先访问根节点,再前序遍历左子树,最后前序遍历右子树。

通过递归调用即可实现。

伪代码如下:```void preOrder(Node* root)if (root != NULL)cout << root->data;preOrder(root->left);preOrder(root->right);}(2)中序遍历和后序遍历与前序遍历类似,中序遍历的流程为:先中序遍历左子树,再访问根节点,最后中序遍历右子树。

后序遍历的流程为:先后序遍历左子树,再后序遍历右子树,最后访问根节点。

也可以通过递归调用实现。

伪代码如下:```void inOrder(Node* root)if (root != NULL)inOrder(root->left);cout << root->data;inOrder(root->right);}void postOrder(Node* root)if (root != NULL)postOrder(root->left);postOrder(root->right);cout << root->data;}五、实验结果与分析我们通过编写测试数据并调用递归遍历算法进行遍历,得到以下结果:(1)前序遍历结果:ABDECFG(2)中序遍历结果:DBEAFCG(3)后序遍历结果:DEBFGCA实验结果与预期相符,表明递归遍历算法编写正确。

数据结构二叉树的实验报告

数据结构二叉树的实验报告

数据结构实验报告1. 实验目的和内容:掌握二叉树基本操作的实现方法2. 程序分析2.1存储结构链式存储2.程序流程2.3关键算法分析算法一:Create(BiNode<T>* &R,T data[],int i,int n)【1】算法功能:创建二叉树【2】算法基本思想:利用顺序存储结构为输入,采用先建立根结点,再建立左右孩子的方法来递归建立二叉链表的二叉树【3】算法空间时间复杂度分析:O(n)【4】代码逻辑:如果位置小于数组的长度则{ 创建根结点将数组的值赋给刚才创建的结点的数据域创建左子树,如果当前结点位置为i,则左孩子位置为2i创建右子树,如果当前结点位置为i,则右孩子位置为2i+1}否则R为空算法二:CopyTree(BiNode<T>*sR,BiNode<T>* &dR))【1】算法功能:复制构造函数【2】算法基本思想:按照先创建根结点,再递归创建左右子树的方法来实现。

【3】算法空间时间复杂度分析:O(n)【4】代码逻辑:如果源二叉树根结点不为空则{创建根结点调用函数自身,创建左子树调用函数自身,创建右子树}将该函数放在复制构造函数中调用,就可以实现复制构造函数算法三:PreOrder(BiNode<T>*R)【1】算法功能:二叉树的前序遍历【2】算法基本思想:这个代码用的是优化算法,提前让当前结点出栈。

【3】算法空间时间复杂度分析:O(n)【4】代码逻辑(伪代码)如果当前结点为非空,则{访问当前结点当前结点入栈将当前结点的左孩子作为当前结点}如果为空{则栈顶结点出栈则将该结点的右孩子作为当前结点}反复执行这两个过程,直到结点为空并且栈空算法四:InOrder(BiNode<T>*R)【1】算法功能:二叉树的中序遍历【2】算法基本思想:递归【3】算法空间时间复杂度分析:未知【4】代码逻辑:如果R为非空:则调用函数自身遍历左孩子访问该结点再调用自身访问该结点的右孩子算法五:LevelOrder(BiNode<T>*R)【1】算法功能:二叉树的层序遍历【2】算法基本思想:【3】算法空间时间复杂度分析:O(n)【4】代码逻辑(伪代码):如果队列不空{对头元素出队访问该元素若该结点的左孩子为非空,则左孩子入队;若该结点的右孩子为非空,则右孩子入队;}算法六:Count(BiNode<T>*R)【1】算法功能:计算结点的个数【2】算法基本思想:递归【3】算法空间时间复杂度分析:未知【4】代码逻辑:如果R不为空的话{调用函数自身计算左孩子的结点数调用函数自身计算右孩子的结点数}template<class T>int BiTree<T>::Count(BiNode<T>*R){if(R==NULL)return 0;else{int m=Count(R->lchild);int n=Count(R->rchild);return m+n+1;}}算法七:Release(BiNode<T>*R)【1】算法功能:释放动态内存【2】算法基本思想:左右子树全部释放完毕后再释放该结点【3】算法空间时间复杂度分析:未知【4】代码逻辑:调用函数自身,释放左子树调用函数自身,释放右子树释放根结点释放二叉树template<class T>void BiTree<T>::Release(BiNode<T>*R) {if(R!=NULL){Release(R->lchild);Release(R->rchild);delete R;}}template<class T>BiTree<T>::~BiTree(){Release(root);}int main(){BiTree<int> BTree(a,10);BiTree<int>Tree(BTree);BTree.PreOrder(BTree.root);cout<<endl;Tree.PreOrder(Tree.root);cout<<endl;BTree.InOrder(BTree.root);cout<<endl;Tree.InOrder(Tree.root);cout<<endl;BTree.PostOrder(BTree.root);cout<<endl;Tree.PostOrder(Tree.root);cout<<endl;BTree.LevelOrder(BTree.root);cout<<endl;Tree.LevelOrder(Tree.root);cout<<endl;int m=BTree.Count(BTree.root);cout<<m<<endl;return 0;}3.测试数据:int a[10]={1,2,3,4,5};1 2 4 5 31 2 4 5 34 25 1 34 5 2 3 11 2 3 4 554.总结:4.1:这次实验大多用了递归的算法,比较好理解。

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

《数据结构》第六次实验报告学生姓名学生班级学生学号指导老师一、实验内容1) 采用二叉树链表作为存储结构,完成二叉树的建立,先序、中序和后序以及按层次遍历的操作,求所有叶子及结点总数的操作。

2) 输出树的深度,最大元,最小元。

二、需求分析遍历二叉树首先有三种方法,即先序遍历,中序遍历和后序遍历。

递归方法比较简单,首先获得结点指针如果指针不为空,且有左子,从左子递归到下一层,如果没有左子,从右子递归到下一层,如果指针为空,则结束一层递归调用。

直到递归全部结束。

下面重点来讲述非递归方法:首先介绍先序遍历:先序遍历的顺序是根左右,也就是说先访问根结点然后访问其左子再然后访问其右子。

具体算法实现如下:如果结点的指针不为空,结点指针入栈,输出相应结点的数据,同时指针指向其左子,如果结点的指针为空,表示左子树访问结束,栈顶结点指针出栈,指针指向其右子,对其右子树进行访问,如此循环,直至结点指针和栈均为空时,遍历结束。

再次介绍中序遍历:中序遍历的顺序是左根右,中序遍历和先序遍历思想差不多,只是打印顺序稍有变化。

具体实现算法如下:如果结点指针不为空,结点入栈,指针指向其左子,如果指针为空,表示左子树访问完成,则栈顶结点指针出栈,并输出相应结点的数据,同时指针指向其右子,对其右子树进行访问。

如此循环直至结点指针和栈均为空,遍历结束。

最后介绍后序遍历:后序遍历的顺序是左右根,后序遍历是比较难的一种,首先需要建立两个栈,一个用来存放结点的指针,另一个存放标志位,也是首先访问根结点,如果结点的指针不为空,根结点入栈,与之对应的标志位也随之入标志位栈,并赋值0,表示该结点的右子还没有访问,指针指向该结点的左子,如果结点指针为空,表示左子访问完成,父结点出栈,与之对应的标志位也随之出栈,如果相应的标志位值为0,表示右子树还没有访问,指针指向其右子,父结点再次入栈,与之对应的标志位也入栈,但要给标志位赋值为1,表示右子访问过。

如果相应的标志位值为1,表示右子树已经访问完成,此时要输出相应结点的数据,同时将结点指针赋值为空,如此循环直至结点指针和栈均为空,遍历结束。

三、详细设计源代码:#include<stdio.h>#define MAX 100 //表示栈的最大容量#define FULL 99//表示栈满#define EMPTY -1//表示栈空typedef struct Tnode //定义结点{char data;//存储结点数据struct Tnode *left;//定义结点左子指针struct Tnode *right;//定义右子指针}Tnode,*Pnode;//声明Tnode类型的变量和指针typedef struct Stack//定义栈{Pnode pnode[MAX];//存放数据int p;//栈顶指针}Stack,*Pstack;//定义Stack类型的变量和指针void Push (Pstack pstack,Pnode pnode)//入栈{pstack->p ++;pstack->pnode[pstack->p] = pnode;//赋值}Pnode Pop(Pstack pstack)//出栈{return pstack->pnode[pstack->p--];}Pnode Top (Pstack pstack)//看栈顶元素{return pstack->pnode[pstack->p];}int Isempty (Pstack pstack)//栈判空{if(pstack->p==EMPTY)return 1;elsereturn 0;;}int Isfull (Pstack pstack )//栈满{if (pstack ->p==FULL)return 1;elsereturn 0;}void Initstack (Pstack pstack)//初始化栈{pstack->p=EMPTY;}void Inittnode(Pnode root,Pnode left,Pnode right,char data)//初始化结点{root->left=left;root->right = right;root->data = data;}void PreorderR(Pnode proot)//递归先序遍历算法{if(proot){printf("%2c",proot->data);PreorderR(proot->left);PreorderR(proot->right);}}void InorderR(Pnode proot)//递归中序遍历算法{if(proot){InorderR(proot->left);printf("%2c",proot->data);InorderR(proot->right);}}void PostorderR(Pnode proot)//递归后序遍历算法{if(proot){PostorderR(proot->left);PostorderR(proot->right);printf("%2c",proot->data);}}void PreorderI(Pnode proot,Pstack pstack)//非递归先序遍历算法{Initstack(pstack);//初始化栈while(proot||!Isempty(pstack))//如果栈空并且结点指针空,则结束循环{if(proot){printf("%2c",proot->data);if(Isfull(pstack))//如果栈满不能执行入栈操作{printf("栈满,不能执行入栈操作!!");return;}Push(pstack,proot);//入栈proot=proot->left;//指针指向左子}else{if(Isempty(pstack))//栈空时不能出栈{printf("栈空,不能执行出栈操作!!");return;}proot = Pop(pstack);//执行出栈操作proot=proot->right;//指针指向右子}}}void InorderI(Pnode proot,Pstack pstack)//非递归中序遍历算法{Initstack(pstack);//初始化栈while(proot||!Isempty(pstack))//循环结束条件{if(proot){if(Isfull(pstack)){printf("栈满,不能执行入栈操作!!");return;}Push(pstack,proot);//执行入栈操作proot = proot->left;//指针指向左子}else{if(Isempty(pstack)){printf("栈空,不能执行出栈操作!!");return ;}proot = Pop(pstack);//出栈printf("%2c",proot->data);//打印数据proot=proot->right;//指针指向右子}}}void PostorderI(Pnode proot,Pstack pstack)//非递归后续遍历算法{int flags[MAX];//定义标志位栈int p =-1;//初始化标志位栈int flag;//存放标志位Initstack(pstack);//初始化栈while(proot||!Isempty(pstack))//循环结束条件{if(proot){if(Isfull(pstack)){printf("栈满,不能执行入栈操作!!");return ;}flags[++p] = 0;//标志位置0,并入栈Push(pstack,proot);//结点入栈proot=proot->left;//指针指向左子}else{proot = Pop(pstack);//指针出栈flag = flags[p--];//相应标志位出栈if(flag==0)//如果标志位为0表示右子还未访问过{flag =1;//将标志位置1,右子已访问flags[++p] = flag;//标志位入栈Push(pstack,proot);//结点入栈proot = proot->right;//指针指向右子}else{printf("%2c",proot->data);//打印数据proot = NULL;//将结点指针置空}}}}void main (){Tnode A,B,C,D,E,F,G;//声明结点变量Stack stack;//声明栈Inittnode(&A,&B,&C,'A');//初始化结点Inittnode(&B,NULL,&D,'B');Inittnode(&C,&E,&F,'C');Inittnode(&D,NULL,NULL,'D');Inittnode(&E,NULL,NULL,'E');Inittnode(&F,&G,NULL,'F');Inittnode(&G,NULL,NULL,'G');printf("你定义的树的结构是:\n");/*一下是调用相应的函数输出遍历结果*/printf("A(B(D)C(E F(G)))\n");printf("=====================下面是遍历结果====================\n");printf("=====================递归先序遍历:====================\n");PreorderR(&A);printf("\n");printf("=====================非递归先序遍历:==================\n");PreorderI(&A,&stack);printf("\n");printf("=====================递归中序遍历:====================\n");InorderR(&A);printf("\n");printf("=====================非递归中序遍历:==================\n");InorderI(&A,&stack);printf("\n");printf("=====================递归后序遍历:====================\n");PostorderR(&A);printf("\n");printf("=====================非递归后序遍历:==================\n");PostorderI(&A,&stack);printf("\n");}五、遇到的问题及解决办法这部分我主要遇到如下两个问题,其内容和解决方法如下所列:执行程序时程序停止运行,其效果如图:解决方法:看到程序停止运行,推测可能的原因:遇到死循环、参数设置不合理或者结构体没有造好。

相关文档
最新文档