二叉树排序算法
- 格式:doc
- 大小:148.50 KB
- 文档页数:11
二叉树先序和中序相同的条件
在计算机科学中,二叉树是一种重要的数据结构,它拥有着很多种有趣的应用,而其中先序和中序的概念也是极其重要的。
先序和中序排列都是用来描述二叉树的排序方式,在其中,有一个非常重要的知识点,就是:当一棵树的先序和中序相同的情况下,有着哪些具体的约束条件呢?
首先,要深刻理解以下概念:先序就是以前序遍历的方式来描述二叉树,中序是以中序遍历的方式来描述二叉树,前序和中序遍历分别以根结点(ROOT)和中间结点(MIDDLE)为分割点,将树分为左右子树,分别进行前序和中序遍历,最终生成前序和中序序列。
其次,当一棵树的先序和中序相同的情况下,这棵树的结构必定具有以下特点:
1.的高度必定是偶数,也就是二叉树的高度必定是2的几次方。
2.于一棵完全二叉树,除了最后一层外,其它所有的层的结点数都必须满足2的n次方-1的条件。
3.于每一个结点来说,若其左儿子结点存在,那么其左儿子结点在先序序列中必定在它前面,在中序序列中也必定在它前面。
4.于每一个结点来说,若其右儿子结点存在,那么其右儿子结点在先序序列中必定在它后面,在中序序列中也必定在它后面。
最后,当一棵树的先序和中序相同的约束条件有了一定的了解之后,就可以更好地运用二叉树这一数据结构。
在实际使用中,以上这些约束条件可以帮助我们更好地利用各种遍历算法,从而更加精确地
解决计算机中出现的一些问题,从而提高计算机解题的效率。
总之,了解和理解当一棵树的先序和中序相同的情况下具有哪些重要的约束条件,是深入学习和使用二叉树的重要前提,也是持续提升计算机解决能力、提高解题效率的关键之一。
⼆叉排序树的判定算法//函数功能:⼆叉排序树的判定算法/*算法思想:根据⼆叉树的特点“其中序遍历序列为有序序列”,对⼆叉树进⾏中序遍历,同时检查当前结点与其中前驱关键字值的⼤⼩。
*///中序遍历过程中判定给定的⼆叉树是否为⼆叉排序树,⼊是返会true,否则返回false//pre指向中序前驱结点,初值为NULL1 typedef struct treeNode2 {3int data; //⼆叉排序树的元素类型为int4struct treeNode *l,*r;5 }treeNode,*BiTree;67/*8中序遍历⼆叉树,root为根节点,pre初始值为null。
910*/1112bool Is_BS_Tree(BiTree root,BiTree pre)13 {14if(!root)15 {//空⼆叉树也是⼆叉排序树,所以返回true。
16return true;17 }18if(Is_BS_Tree(root->l,pre))19 {//若左⼦树是⼆叉排序树。
20//是否为⼆叉排序树取决于前驱值和根节点值的⼤⼩。
21if((pre==null)||(pre->data<root->data))22 {23 pre=root;24//再次判断右⼦树是否为⼆叉排序树。
25return Is_BS_Tree(root->l,pre);26 }27 }28//以上情况出现异常,则返回false。
29return false;30 }。
数据结构与算法系列研究五——树、⼆叉树、三叉树、平衡排序⼆叉树AVL树、⼆叉树、三叉树、平衡排序⼆叉树AVL⼀、树的定义树是计算机算法最重要的⾮线性结构。
树中每个数据元素⾄多有⼀个直接前驱,但可以有多个直接后继。
树是⼀种以分⽀关系定义的层次结构。
a.树是n(≥0)结点组成的有限集合。
{N.沃恩}(树是n(n≥1)个结点组成的有限集合。
{D.E.Knuth})在任意⼀棵⾮空树中:⑴有且仅有⼀个没有前驱的结点----根(root)。
⑵当n>1时,其余结点有且仅有⼀个直接前驱。
⑶所有结点都可以有0个或多个后继。
b. 树是n(n≥0)个结点组成的有限集合。
在任意⼀棵⾮空树中:⑴有⼀个特定的称为根(root)的结点。
⑵当n>1时,其余结点分为m(m≥0)个互不相交的⼦集T1,T2,…,Tm。
每个集合本⾝⼜是⼀棵树,并且称为根的⼦树(subtree)树的固有特性---递归性。
即⾮空树是由若⼲棵⼦树组成,⽽⼦树⼜可以由若⼲棵更⼩的⼦树组成。
树的基本操作1、InitTree(&T) 初始化2、DestroyTree(&T) 撤消树3、CreatTree(&T,F) 按F的定义⽣成树4、ClearTree(&T) 清除5、TreeEmpty(T) 判树空6、TreeDepth(T) 求树的深度7、Root(T) 返回根结点8、Parent(T,x) 返回结点 x 的双亲9、Child(T,x,i) 返回结点 x 的第i 个孩⼦10、InsertChild(&T,&p,i,x) 把 x 插⼊到 P的第i棵⼦树处11、DeleteChild(&T,&p,i) 删除结点P的第i棵⼦树12、traverse(T) 遍历树的结点:包含⼀个数据元素及若⼲指向⼦树的分⽀。
●结点的度: 结点拥有⼦树的数⽬●叶结点: 度为零的结点●分枝结点: 度⾮零的结点●树的度: 树中各结点度的最⼤值●孩⼦: 树中某个结点的⼦树的根●双亲: 结点的直接前驱●兄弟: 同⼀双亲的孩⼦互称兄弟●祖先: 从根结点到某结点j 路径上的所有结点(不包括指定结点)。
二叉排序树1.二叉排序树定义二叉排序树(Binary Sort Tree)或者是一棵空树;或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于根结点的值;若右子树不空,则右子树上所有结点的值均大于根结点的值。
(2)左右子树也都是二叉排序树,如图6-2所示。
2.二叉排序树的查找过程由其定义可见,二叉排序树的查找过程为:(1)若查找树为空,查找失败。
(2)查找树非空,将给定值key与查找树的根结点关键码比较。
(3)若相等,查找成功,结束查找过程,否则:①当给值key小于根结点关键码,查找将在以左孩子为根的子树上继续进行,转(1)。
②当给值key大于根结点关键码,查找将在以右孩子为根的子树上继续进行,转(1)。
3.二叉排序树插入操作和构造一棵二叉排序树向二叉排序树中插入一个结点的过程:设待插入结点的关键码为key,为将其插入,先要在二叉排序树中进行查找,若查找成功,按二叉排序树定义,该插入结点已存在,不用插入;查找不成功时,则插入之。
因此,新插入结点一定是作为叶子结点添加上去的。
构造一棵二叉排序树则是逐个插入结点的过程。
对于关键码序列为:{63,90,70,55,67,42,98,83,10,45,58},则构造一棵二叉排序树的过程如图6-3所示。
4.二叉排序树删除操作从二叉排序树中删除一个结点之后,要求其仍能保持二叉排序树的特性。
设待删结点为*p(p为指向待删结点的指针),其双亲结点为*f,删除可以分三种情况,如图6-4所示。
(1)*p结点为叶结点,由于删去叶结点后不影响整棵树的特性,所以,只需将被删结点的双亲结点相应指针域改为空指针,如图6-4(a)所示。
(2)*p结点只有右子树或只有左子树,此时,只需将或替换*f结点的*p子树即可,如图6-4(b)、(c)所示。
(3)*p结点既有左子树又有右子树,可按中序遍历保持有序地进行调整,如图6-4(d)、(e)所示。
设删除*p结点前,中序遍历序列为:① P为F的左子女时有:…,Pi子树,P,Pj,S子树,Pk,Sk子树,…,P2,S2子树,P1,S1子树,F,…。
堆排序的具体过程
堆排序是一种高效的排序算法,它使用堆数据结构来进行排序。
堆是一种树状结构,具有以下特点:
1. 堆是一棵完全二叉树;
2. 堆中每个节点的值都大于或等于(或小于或等于)其子节点的值。
堆排序的具体过程如下:
1. 构建堆:将待排序的序列构建成一个大根堆(或小根堆),堆的根节点就是序列中的最大(或最小)值。
构建堆的过程可以使用自上而下的调整方法或自下而上的调整方法。
2. 排序:将堆顶元素(即序列中的最大或最小值)与堆的最后一个元素进行交换,然后将堆的大小减一(相当于将最大或最小值从堆中删除)。
然后对堆进行调整,使其满足堆的性质。
重复这个过程,直到堆的大小为1,排序完成。
堆排序的时间复杂度为O(nlogn),它是一种不稳定的排序算法,因为在构建堆的过程中,可能会改变序列中相同元素的顺序。
- 1 -。
二叉排序树查找的递归算法介绍二叉排序树(Binary Search Tree),也称二叉查找树、有序二叉树或排序二叉树,是一种常用的数据结构。
它具有以下特点:•每个节点都包含一个键值和对应的数据。
•左子树中的所有节点的键值都小于根节点的键值。
•右子树中的所有节点的键值都大于根节点的键值。
•左右子树也分别是二叉排序树。
二叉排序树支持高效的查找、插入和删除操作,其中查找操作是利用递归实现的。
本文将详细介绍二叉排序树查找的递归算法。
二叉排序树的定义二叉排序树的定义如下:class TreeNode:def __init__(self, key, data):self.key = keyself.data = dataself.left = Noneself.right = Noneclass BinarySearchTree:def __init__(self):self.root = None在二叉排序树中,每个节点都是一个TreeNode对象,包含键值key和对应的数据data。
left和right分别指向左子树和右子树的根节点。
树的根节点由BinarySearchTree对象的root属性表示。
二叉排序树查找的递归算法二叉排序树的查找操作是利用递归实现的,其具体算法如下:1.如果待查找的键值等于当前节点的键值,返回当前节点的数据。
2.如果待查找的键值小于当前节点的键值,递归在左子树中查找。
3.如果待查找的键值大于当前节点的键值,递归在右子树中查找。
4.如果在左子树或右子树中找不到对应的键值,则返回空。
下面是二叉排序树查找的递归算法的代码实现:def search_recursive(node, key):if node is None or node.key == key:return node.dataelif key < node.key:return search_recursive(node.left, key)else:return search_recursive(node.right, key)在上述代码中,node表示当前节点,key表示待查找的键值。
以二叉树或树作为表的组织形式,称为树表,它是一类动态查找表,不仅适合于数据查找,也适合于表插入和删除操作。
常见的树表:二叉排序树平衡二叉树B-树B+树9.3.1 二叉排序树二叉排序树(简称BST)又称二叉查找(搜索)树,其定义为:二叉排序树或者是空树,或者是满足如下性质(BST性质)的二叉树:❶若它的左子树非空,则左子树上所有节点值(指关键字值)均小于根节点值;❷若它的右子树非空,则右子树上所有节点值均大于根节点值;❸左、右子树本身又各是一棵二叉排序树。
注意:二叉排序树中没有相同关键字的节点。
二叉树结构满足BST性质:节点值约束二叉排序树503080209010854035252388例如:是二叉排序树。
66不试一试二叉排序树的中序遍历序列有什么特点?二叉排序树的节点类型如下:typedef struct node{KeyType key;//关键字项InfoType data;//其他数据域struct node*lchild,*rchild;//左右孩子指针}BSTNode;二叉排序树可看做是一个有序表,所以在二叉排序树上进行查找,和二分查找类似,也是一个逐步缩小查找范围的过程。
1、二叉排序树上的查找Nk< bt->keybtk> bt->key 每一层只和一个节点进行关键字比较!∧∧p查找到p所指节点若k<p->data,并且p->lchild=NULL,查找失败。
若k>p->data,并且p->rchild=NULL,查找失败。
查找失败的情况加上外部节点一个外部节点对应某内部节点的一个NULL指针递归查找算法SearchBST()如下(在二叉排序树bt上查找关键字为k的记录,成功时返回该节点指针,否则返回NULL):BSTNode*SearchBST(BSTNode*bt,KeyType k){if(bt==NULL||bt->key==k)//递归出口return bt;if(k<bt->key)return SearchBST(bt->lchild,k);//在左子树中递归查找elsereturn SearchBST(bt->rchild,k);//在右子树中递归查找}在二叉排序树中插入一个关键字为k的新节点,要保证插入后仍满足BST性质。
平衡树——特点:所有结点左右子树深度差≤1排序树——特点:所有结点―左小右大字典树——由字符串构成的二叉排序树判定树——特点:分支查找树(例如12个球如何只称3次便分出轻重)带权树——特点:路径带权值(例如长度)最优树——是带权路径长度最短的树,又称Huffman树,用途之一是通信中的压缩编码。
1.1 二叉排序树:或是一棵空树;或者是具有如下性质的非空二叉树:(1)若左子树不为空,左子树的所有结点的值均小于根的值;(2)若右子树不为空,右子树的所有结点均大于根的值;(3)它的左右子树也分别为二叉排序树。
例:二叉排序树如图9.7:二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。
中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。
每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。
搜索,插入,删除的复杂度等于树高,期望O(logn),最坏O(n)(数列有序,树退化成线性表).虽然二叉排序树的最坏效率是O(n),但它支持动态查询,且有很多改进版的二叉排序树可以使树高为O(logn),如SBT,AVL,红黑树等.故不失为一种好的动态排序方法.2.2 二叉排序树b中查找在二叉排序树b中查找x的过程为:1. 若b是空树,则搜索失败,否则:2. 若x等于b的根节点的数据域之值,则查找成功;否则:3. 若x小于b的根节点的数据域之值,则搜索左子树;否则:4. 查找右子树。
[cpp]view plaincopyprint?1.Status SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p){2. //在根指针T所指二叉排序樹中递归地查找其关键字等于key的数据元素,若查找成功,3. //则指针p指向该数据元素节点,并返回TRUE,否则指针P指向查找路径上访问的4. //最好一个节点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL5. if(!T){ p=f; return FALSE;} //查找不成功6. else if EQ(key, T->data.key) {P=T; return TRUE;} //查找成功7. else if LT(key,T->data.key)8. return SearchBST(T->lchild, key, T, p); //在左子树继续查找9. else return SearchBST(T->rchild, key, T, p); //在右子树继续查找10.}2.3 在二叉排序树插入结点的算法向一个二叉排序树b中插入一个结点s的算法,过程为:1. 若b是空树,则将s所指结点作为根结点插入,否则:2. 若s->data等于b的根结点的数据域之值,则返回,否则:3. 若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中,否则:4. 把s所指结点插入到右子树中。
二叉树的快速排序、归并排序方法一、快速排序快速排序采用的是分治法策略,其基本思路是先选定一个基准数(一般取第一个元素),将待排序序列抽象成两个子序列:小于基准数的子序列和大于等于基准数的子序列,然后递归地对这两个子序列排序。
1. 递归实现(1)选定基准数题目要求采用第一个元素作为基准数,因此可以直接将其取出。
(2)划分序列接下来需要将待排序序列划分成两个子序列。
我们定义两个指针 i 和 j,从待排序序列的第二个元素和最后一个元素位置开始,分别向左和向右扫描,直到 i 和 j 相遇为止。
在扫描过程中,将小于等于基准数的元素移到左边(即与左侧序列交换),将大于基准数的元素移到右边(即与右侧序列交换)。
当 i=j 时,扫描结束。
(3)递归排序子序列完成划分后,左右两个子序列就确定了下来。
接下来分别对左右两个子序列递归调用快速排序算法即可。
2. 非递归实现上述方法是快速排序的递归实现。
对于大量数据或深度递归的情况,可能会出现栈溢出等问题,因此还可以使用非递归实现。
非递归实现采用的是栈结构,将待排序序列分成若干子序列后,依次将其入栈并标注其位置信息,然后将栈中元素依次出栈并分割、排序,直至栈为空。
二、归并排序归并排序同样采用的是分治思想。
其基本思路是将待排序序列拆分成若干个子序列,直至每个子序列只有一个元素,然后将相邻的子序列两两合并,直至合并成一个有序序列。
1. 递归实现(1)拆分子序列归并排序先将待排序序列进行拆分,具体方法是将序列平分成两个子序列,然后递归地对子序列进行拆分直至每个子序列只剩下一个元素。
(2)合并有序子序列在完成子序列的拆分后,接下来需要将相邻的子序列两两合并为一个有序序列。
我们先定义三个指针 i、j 和 k,分别指向待合并的左侧子序列、右侧子序列和合并后的序列。
在进行合并时,从两个子序列的起始位置开始比较,将两个子序列中较小的元素移动到合并后的序列中。
具体操作如下:- 当左侧子序列的第一个元素小于等于右侧子序列的第一个元素时,将左侧子序列的第一个元素移动到合并后的序列中,并将指针 i 和 k 分别加 1。
树、⼆叉树、查找算法总结树的定义形式化定义树:T={D,R }。
D是包含n个结点的有限集合(n≥0)。
当n=0时为空树,否则关系R满⾜以下条件:l 有且仅有⼀个结点d0∈D,它对于关系R来说没有前驱结点,结点d0称作树的根结点。
l 除根结点外,每个结点有且仅有⼀个前驱结点。
l D中每个结点可以有零个或多个后继结点。
递归定义树是由n(n≥0)个结点组成的有限集合(记为T)。
其中:l 如果n=0,它是⼀棵空树,这是树的特例;l 如果n>0,这n个结点中存在⼀个唯⼀结点作为树的根结点(root),其余结点可分为m (m≥0)个互不相交的有限⼦集T1、T2、…、Tm,⽽每个⼦集本⾝⼜是⼀棵树,称为根结点root的⼦树。
ð 树中所有结点构成⼀种层次关系!树的基本术语度结点的度:⼀个结点的⼦树的个数树的度:各节点的度的最⼤值。
通常将度为m的树成为m次树或m叉树结点分⽀结点:度不为0的结点(也称⾮终端结点)度为1的结点成为单分⽀结点,度为2的结点称为双分⽀结点叶结点:度为0的结点路径与路径长度路径:两个结点di和dj的结点序列(di,di1,di2,…,dj)。
其中<dx,dy>是分⽀。
路径长度:等于路径所通过的结点数⽬减1(即路径上的分⽀数⽬)结点的层次和树⾼度层次:根结点层次为1,它的孩⼦结点层次为2。
以此类推。
树的⾼度(深度):结点中的最⼤层次;有序树和⽆序树有序树:若树中各结点的⼦树是按照⼀定的次序从左向右安排的,且相对次序是不能随意变换的⽆序树:和上⾯相反森林只要把树的根结点删去就成了森林。
反之,只要给n棵独⽴的树加上⼀个结点,并把这n棵树作为该结点的⼦树,则森林就变成了⼀颗树。
树的性质性质1:树中的结点数等于所有结点的度数之和加1。
证明:树的每个分⽀记为⼀个度,度数和=分⽀和,⽽再给根节点加个分⽀性质2:度为m的树中第i层上⾄多有mi-1个结点(i≥1)。
性质3 ⾼度为h的m次树⾄多有个结点。
实验报告课程名称:数据结构实验课程实验四、串的基本操作练习一、实验目的1. 掌握二叉树的存储实现2. 掌握二叉树的遍历思想3. 掌握二叉树的常见算法的程序实现二、实验环境VC++6.0三、实验内容1.输入字符序列,建立二叉树的二叉链表结构。
(可以采用先序序列)2.实现二叉树的先序、中序、后序的递归遍历算法。
3.实现二叉树的先序、中序、后序的非递归遍历算法。
4.求二叉树的高度。
5.求二叉树的结点个数。
6.求二叉树的叶子结点的个数。
四、实验要求:分别编写实现上述算法的子函数,并编写一个主函数,在主函数中设计一个简单的菜单,分别调用上述子函数。
五、实验步骤和结果1.打开vc,新建文本,命名二叉树算法,编写代码。
2.编写代码:#include <stdio.h>#include <stdlib.h>#define STACK_INIT_SIZE 100#define STACKINCREMENT 10int i=0;/*--------------------------------------建立堆栈------------------------------------------*/typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;} BiTNode,*BiTree;//树类型typedef struct SqStack{BiTNode *base;BiTNode *top;int stacksize;} SqStack;//栈类型void InitStack(SqStack *S)//创建二叉树{S->base=(BiTNode*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));S->top=S->base;S->stacksize=STACK_INIT_SIZE;}void Push(SqStack *S,BiTNode e)//进栈{if(S->top - S->base >= S->stacksize)//如果栈空间不足{S->base=(BiTNode*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(B iTNode));S->top=S->base+S->stacksize;S->stacksize+=STACKINCREMENT;}*(S->top)=e;S->top++;}BiTNode Pop(SqStack *S)//出栈{S->top --;return *S->top;}int StackEmpty(SqStack *S)//判断栈是否非空{if(S->top == S->base )return 1;elsereturn 0;}/*---------------------------------------------递归部分-------------------------------------------*/BiTree Create(BiTree T)//建立二叉树{char ch;ch=getchar();if(ch=='#')T=NULL;else{if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))printf("申请内存空间失败!");T->data=ch;T->lchild=Create(T->lchild);T->rchild=Create(T->rchild);}return T;}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;}/*int Sumleaf(BiTree T)//老师课堂上的计算叶子数的代码,没有问题{if(!(T->lchild&&T->rchild))return 1;elsereturn(Sumleaf(T->lchild)+Sumleaf(T->rchild));}*/int PreOrder_1(BiTree T)//先序递归{if(T){printf("%c",T->data);//根节点i++;PreOrder_1(T->lchild);PreOrder_1(T->rchild);}return i;}void InOrder_1(BiTree T)//中序递归{if(T){InOrder_1(T->lchild);printf("%c",T->data);//根节点InOrder_1(T->rchild);}}void PostOrder_1(BiTree T)//后序递归{if(T){PostOrder_1(T->lchild);PostOrder_1(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;}/*-------------------------------------非递归部分----------------------------------------*/{SqStack S;BiTree p=T,q;q=(BiTNode *)malloc(sizeof(BiTNode));InitStack(&S);if(p)Push(&S,*p);while(!StackEmpty(&S)){p=q;*p=Pop(&S);//移到叶子时,出栈,输出出栈元素printf("%c",p->data);if(p->rchild)//如果有右孩子,访问右孩子,并沿右孩子移位Push(&S,*p->rchild);if(p->lchild)//如果没有右孩子,访问左孩子,并移到左孩子Push(&S,*p->lchild);}}void InOrder_2(BiTree T)//中序非递归{SqStack S;BiTree p,q;p=T;InitStack(&S);q=(BiTNode *)malloc(sizeof(BiTNode));while(p||!StackEmpty(&S)){if(p){Push(&S,*p);p=p->lchild;}else{p=q;*p=Pop(&S);printf("%c",p->data);p=p->rchild;}}}{int mark[100];//标示int t=0;int top=-1;//下标SqStack S;BiTree p=T,q;InitStack(&S);q=(BiTNode *)malloc(sizeof(BiTNode));if(p&&(p->lchild||p->rchild)){do{while((p->lchild||p->rchild)&&mark[top+1]!=2)//循环直到让p向左滑到叶子节点{top++;Push(&S,*p);//每循环一次,当前结点入栈mark[top]=1;//结点第一次入栈时,标志为1if(p->lchild)p=p->lchild;//找最左子树elseif(p->rchild)p=p->rchild;}if(p)printf("%c",p->data);p=q;*p=Pop(&S);top--;//出栈,下标归位if(!p->rchild||!p->lchild)//防止出现不必要的再次入栈mark[top+1]=2;if(mark[top+1]==1&&p->rchild)//若结点是第一次出栈,则再入栈{top++;Push(&S,*p);mark[top]=2;//结点第二次入栈时,标志为2p=p->rchild;//访问右子树mark[top+1]=0;}if(mark[0]==2&&t==0)//当栈剩下最后一个结点的时候,把下标初始化。
{int i;t++;for(i=0;i<100;i++){mark[i]=0;}}}while (top!=-1&&!StackEmpty(&S)&&p);printf("%c",p->data);//输出根节点}elseif(p)printf("%c",p->data);//当树仅有一个结点时}void main(){BiTree Ta;int sum,dep,total;printf("输入数据创建二叉树");Ta=Create(Ta);printf("************************递归遍历***************************");printf("\n递归先序遍历:\n");total=PreOrder_1(Ta);printf("\n递归中序遍历:\n");InOrder_1(Ta);printf("\n递归后序遍历:\n");PostOrder_1(Ta);sum=Sumleaf(Ta);printf("\n");printf("*******************结点总数叶子数和高度********************");printf("\n该二叉树结点总数为:%d",total);printf("\n叶子总数为:%d",sum);dep=Depth(Ta);printf("\n高度为:%d\n",dep);printf("***********************非递归遍历**************************");printf("\n非递归先序遍历:\n");PreOrder_2(Ta);printf("\n非递归中序遍历:\n");InOrder_2(Ta);printf("\n非递归后序遍历:\n");PostOrder_2(Ta);printf("\n\n");}六、实验结果和讨论1.首先,代码,修改语法错误,调试。