C++二叉树的前序,中序,后序,层序遍历的递归算法55555
前序序列中序序列后序序列的规律
标题:前序序列、中序序列和后序序列的规律分析1.概述前序序列、中序序列和后序序列是树的三种遍历方式,它们分别描述了在树结构中节点的访问顺序。
这三种遍历方式具有一定的规律,本文将对这些规律进行分析和总结。
2.前序序列、中序序列和后序序列的定义2.1 前序序列:节点的访问顺序是先访问根节点,然后依次访问左子树和右子树。
2.2 中序序列:节点的访问顺序是先访问左子树,然后访问根节点,最后访问右子树。
2.3 后序序列:节点的访问顺序是先访问左子树,然后访问右子树,最后访问根节点。
3.前序序列、中序序列和后序序列的规律分析3.1 规律一:对于任意一颗树,它的前序序列中的第一个节点必定是根节点。
3.2 规律二:对于任意一颗树,它的中序序列中,根节点的位置将左右子树分割开来。
3.3 规律三:对于任意一颗树,它的后序序列中的最后一个节点必定是根节点。
3.4 规律四:对于同一颗树,其前序序列和后序序列的第二个节点是该树的左子树的根节点。
4.应用举例4.1 求解建立二叉树4.1.1 根据前序序列和中序序列建立二叉树4.1.2 根据中序序列和后序序列建立二叉树4.2 根据前序序列和后序序列求解树的唯一性5.总结前序序列、中序序列和后序序列的规律分析,有助于我们更好地理解树的结构和遍历方式,从而在树的操作中提供了很好的指导。
在实际应用中,可根据这些规律来建立二叉树,求解树的唯一性等问题。
希望通过对这些规律的深入理解,能够更加灵活地应用于相关领域的问题解决中。
6.参考文献[1] 《数据结构与算法分析》,作者:Mark Allen Weiss[2] 《算法导论》,作者:Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein致谢感谢所有对本文撰写提供过帮助的人,包括对数据结构和算法有深入研究的学者们,以及对本文提出宝贵意见和建议的朋友们。
数据结构(二十四)二叉树的链式存储结构(二叉链表)
数据结构(⼆⼗四)⼆叉树的链式存储结构(⼆叉链表) ⼀、⼆叉树每个结点最多有两个孩⼦,所以为它设计⼀个数据域和两个指针域,称这样的链表叫做⼆叉链表。
⼆、结点结构包括:lchild左孩⼦指针域、data数据域和rchild右孩⼦指针域。
三、⼆叉链表的C语⾔代码实现:#include "string.h"#include "stdio.h"#include "stdlib.h"#include "io.h"#include "math.h"#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* ⽤于构造⼆叉树********************************** */int index=1;typedef char String[24]; /* 0号单元存放串的长度 */String str;Status StrAssign(String T,char *chars){int i;if(strlen(chars)>MAXSIZE)return ERROR;else{T[0]=strlen(chars);for(i=1;i<=T[0];i++)T[i]=*(chars+i-1);return OK;}}/* ************************************************ */typedef char TElemType;TElemType Nil=''; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ",e);return OK;}typedef struct BiTNode /* 结点结构 */{TElemType data; /* 结点数据 */struct BiTNode *lchild,*rchild; /* 左右孩⼦指针 */}BiTNode,*BiTree;/* 构造空⼆叉树T */Status InitBiTree(BiTree *T){*T=NULL;return OK;}/* 初始条件: ⼆叉树T存在。
二叉树的遍历及常用算法
⼆叉树的遍历及常⽤算法⼆叉树的遍历及常⽤算法遍历的定义:按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;遍历的重要性:当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;遍历思路:⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作三种遍历次序:根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;设:L为遍历左⼦树,D为访问根结点,R为遍历右⼦树,且L必须位于R的前⾯可以得出以下三种不同的遍历次序:先序遍历操作次序为DLR,⾸先访问根结点,其次遍历根的左⼦树,最后遍历根右⼦树,对每棵⼦树同样按这三步(先根、后左、再右)进⾏中序遍历操作次序为LDR,⾸先遍历根的左⼦树,其次访问根结点,最后遍历根右⼦树,对每棵⼦树同样按这三步(先左、后根、再右)进⾏后序遍历操作次序为LRD,⾸先遍历根的左⼦树,其次遍历根的右⼦树,最后访问根结点,对每棵⼦树同样按这三步(先左、后右、最后根)进⾏层次遍历层次遍历即按照从上到下从左到右的顺序依次遍历所有节点,实现层次遍历通常需要借助⼀个队列,将接下来要遍历的结点依次加⼊队列中;遍历的应⽤“遍历”是⼆叉树各种操作的基础,可以在遍历过程中对结点进⾏各种操作,如:对于⼀棵已知⼆叉树求⼆叉树中结点的个数求⼆叉树中叶⼦结点的个数;求⼆叉树中度为1的结点个数求⼆叉树中度为2的结点个数5求⼆叉树中⾮终端结点个数交换结点左右孩⼦判定结点所在层次等等...C语⾔实现:#include <stdio.h>//⼆叉链表数据结构定义typedef struct TNode {char data;struct TNode *lchild;struct TNode *rchild;} *BinTree, BinNode;//初始化//传⼊⼀个指针令指针指向NULLvoid initiate(BinTree *tree) {*tree = NULL;}//创建树void create(BinTree *BT) {printf("输⼊当前结点值: (0则创建空节点)\n");char data;scanf(" %c", &data);//连续输⼊整形和字符时.字符变量会接受到换⾏,所以加空格if (data == 48) {*BT = NULL;return;} else {//创建根结点//注意开辟的空间⼤⼩是结构体的⼤⼩⽽不是结构体指针⼤⼩,写错了不会⽴马产⽣问题,但是后续在其中存储数据时极有可能出现内存访问异常(飙泪....) *BT = malloc(sizeof(struct TNode));//数据域赋值(*BT)->data = data;printf("输⼊节点 %c 的左孩⼦ \n", data);create(&((*BT)->lchild));//递归创建左⼦树printf("输⼊节点 %c 的右孩⼦ \n", data);create(&((*BT)->rchild));//递归创建右⼦树}}//求双亲结点(⽗结点)BinNode *Parent(BinTree tree, char x) {if (tree == NULL)return NULL;else if ((tree->lchild != NULL && tree->lchild->data == x) || (tree->rchild != NULL && tree->rchild->data == x))return tree;else{BinNode *node1 = Parent(tree->lchild, x);BinNode *node2 = Parent(tree->rchild, x);return node1 != NULL ? node1 : node2;}}//先序遍历void PreOrder(BinTree tree) {if (tree) {//输出数据printf("%c ", tree->data);//不为空则按顺序继续递归判断该节点的两个⼦节点PreOrder(tree->lchild);PreOrder(tree->rchild);}}//中序void InOrder(BinTree tree) {if (tree) {InOrder(tree->lchild);printf("%c ", tree->data);InOrder(tree->rchild);}}//后序void PostOrder(BinTree tree) {if (tree) {PostOrder(tree->lchild);PostOrder(tree->rchild);printf("%c ", tree->data);}}//销毁结点递归free所有节点void DestroyTree(BinTree *tree) {if (*tree != NULL) {printf("free %c \n", (*tree)->data);if ((*tree)->lchild) {DestroyTree(&((*tree)->lchild));}if ((*tree)->rchild) {DestroyTree(&((*tree)->rchild));}free(*tree);*tree = NULL;}}// 查找元素为X的结点使⽤的是层次遍历BinNode *FindNode(BinTree tree, char x) {if (tree == NULL) {return NULL;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];if (current->data == x) {return current;}front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}return NULL;}//层次遍历// 查找元素为X的结点使⽤的是层次遍历void LevelOrder(BinTree tree) {if (tree == NULL) {return;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];printf("%2c", current->data);front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}}//查找x的左孩⼦BinNode *Lchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->lchild;}return NULL;}//查找x的右孩⼦BinNode *Rchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->rchild;}return NULL;}//求叶⼦结点数量int leafCount(BinTree *tree) {if (*tree == NULL)return 0;//若左右⼦树都为空则该节点为叶⼦,且后续不⽤接续递归了else if (!(*tree)->lchild && !(*tree)->rchild)return 1;else//若当前结点存在⼦树,则递归左右⼦树, 结果相加return leafCount(&((*tree)->lchild)) + leafCount(&((*tree)->rchild));}//求⾮叶⼦结点数量int NotLeafCount(BinTree *tree) {if (*tree == NULL)return 0;//若该结点左右⼦树均为空,则是叶⼦,且不⽤继续递归else if (!(*tree)->lchild && !(*tree)->rchild)return 0;else//若当前结点存在左右⼦树,则是⾮叶⼦结点(数量+1),在递归获取左右⼦树中的⾮叶⼦结点,结果相加 return NotLeafCount(&((*tree)->lchild)) + NotLeafCount(&((*tree)->rchild)) + 1;}//求树的⾼度(深度)int DepthCount(BinTree *tree) {if (*tree == NULL)return 0;else{//当前节点不为空则深度+1 在加上⼦树的⾼度,int lc = DepthCount(&((*tree)->lchild)) + 1;int rc = DepthCount(&((*tree)->rchild)) + 1;return lc > rc?lc:rc;// 取两⼦树深度的最⼤值 }}//删除左⼦树void RemoveLeft(BinNode *node){if (!node)return;if (node->lchild)DestroyTree(&(node->lchild));node->lchild = NULL;}//删除右⼦树void RemoveRight(BinNode *node){if (!node)return;if (node->rchild)DestroyTree(&(node->rchild));node->rchild = NULL;}int main() {BinTree tree;create(&tree);BinNode *node = Parent(tree, 'G');printf("G的⽗结点为%c\n",node->data);BinNode *node2 = Lchild(tree, 'D');printf("D的左孩⼦结点为%c\n",node2->data);BinNode *node3 = Rchild(tree, 'D');printf("D的右孩⼦结点为%c\n",node3->data);printf("先序遍历为:");PreOrder(tree);printf("\n");printf("中序遍历为:");InOrder(tree);printf("\n");printf("后序遍历为:");PostOrder(tree);printf("\n");printf("层次遍历为:");LevelOrder(tree);printf("\n");int a = leafCount(&tree);printf("叶⼦结点数为%d\n",a);int b = NotLeafCount(&tree);printf("⾮叶⼦结点数为%d\n",b);int c = DepthCount(&tree);printf("深度为%d\n",c);//查找F节点BinNode *node4 = FindNode(tree,'C');RemoveLeft(node4);printf("删除C的左孩⼦后遍历:");LevelOrder(tree);printf("\n");RemoveRight(node4);printf("删除C的右孩⼦后遍历:");LevelOrder(tree);printf("\n");//销毁树printf("销毁树 \n");DestroyTree(&tree);printf("销毁后后遍历:");LevelOrder(tree);printf("\n");printf("Hello, World!\n");return 0;}测试:测试数据为下列⼆叉树:运⾏程序复制粘贴下列内容:ABDGHECKFIJ特别感谢:iammomo。
数据结构二叉树先序中序后序考研题目
数据结构二叉树先序中序后序考研题目
以下是一些关于二叉树先序、中序和后序遍历的考研题目:
1. 已知二叉树的先序遍历序列为 "A B D E C F",中序遍历序列为 "D B E A F C",请画出该二叉树。
2. 已知二叉树的中序遍历序列为 "D B E A F C",后序遍历序列为 "D E B F C A",请画出该二叉树。
3. 给定一棵二叉树的先序遍历序列为 "A B D E F C",中序遍历序列为 "D B E F A C",请写出该二叉树的后序遍历序列。
4. 请写出一棵二叉树的先序遍历序列为 "A B D E C F",中序遍历序列为 "D B E A F C",后序遍历序列为 "D E B F C A" 的二叉树。
5. 已知一棵二叉树的中序遍历序列为 "D B E A F C",后序遍历序列为 "D E B F C A",请写出该二叉树的先序遍历序列。
6. 给定一棵二叉树的先序遍历序列为 "A B D E F C",后序遍历序列为 "D E F B C A",请写出该二叉树的中序遍历序列。
以上题目可以帮助你练习理解二叉树的遍历方式及其序列之间的关系。
二叉树遍历(前序、中序、后序、层次、广度优先、深度优先遍历)
⼆叉树遍历(前序、中序、后序、层次、⼴度优先、深度优先遍历)⽬录转载:⼆叉树概念⼆叉树是⼀种⾮常重要的数据结构,⾮常多其他数据结构都是基于⼆叉树的基础演变⽽来的。
对于⼆叉树,有深度遍历和⼴度遍历,深度遍历有前序、中序以及后序三种遍历⽅法,⼴度遍历即我们寻常所说的层次遍历。
由于树的定义本⾝就是递归定义,因此採⽤递归的⽅法去实现树的三种遍历不仅easy理解并且代码⾮常简洁,⽽对于⼴度遍历来说,须要其他数据结构的⽀撑。
⽐⽅堆了。
所以。
对于⼀段代码来说,可读性有时候要⽐代码本⾝的效率要重要的多。
四种基本的遍历思想前序遍历:根结点 ---> 左⼦树 ---> 右⼦树中序遍历:左⼦树---> 根结点 ---> 右⼦树后序遍历:左⼦树 ---> 右⼦树 ---> 根结点层次遍历:仅仅需按层次遍历就可以⽐如。
求以下⼆叉树的各种遍历前序遍历:1 2 4 5 7 8 3 6中序遍历:4 2 7 5 8 1 3 6后序遍历:4 7 8 5 2 6 3 1层次遍历:1 2 3 4 5 6 7 8⼀、前序遍历1)依据上⽂提到的遍历思路:根结点 ---> 左⼦树 ---> 右⼦树,⾮常easy写出递归版本号:public void preOrderTraverse1(TreeNode root) {if (root != null) {System.out.print(root.val+" ");preOrderTraverse1(root.left);preOrderTraverse1(root.right);}}2)如今讨论⾮递归的版本号:依据前序遍历的顺序,优先訪问根结点。
然后在訪问左⼦树和右⼦树。
所以。
对于随意结点node。
第⼀部分即直接訪问之,之后在推断左⼦树是否为空,不为空时即反复上⾯的步骤,直到其为空。
若为空。
则须要訪问右⼦树。
注意。
在訪问过左孩⼦之后。
数据结构先序中序后序理解
数据结构先序中序后序理解数据结构是计算机科学中的重要概念之一,它是指一组数据的组织方式以及对这组数据进行操作的方法。
在学习数据结构的过程中,我们经常会遇到先序、中序和后序这三个概念。
它们是用来描述二叉树的遍历方式的,也可以用来表示表达式的计算顺序。
本文将从先序、中序和后序这三个角度来解释数据结构的含义和应用。
一、先序遍历先序遍历是指按照根节点、左子树、右子树的顺序访问二叉树的节点。
在先序遍历中,我们首先访问根节点,然后递归地遍历左子树和右子树。
先序遍历的应用非常广泛,比如在文件系统的目录结构中,我们可以使用先序遍历来列出所有的文件和文件夹。
二、中序遍历中序遍历是指按照左子树、根节点、右子树的顺序访问二叉树的节点。
在中序遍历中,我们首先递归地遍历左子树,然后访问根节点,最后再递归地遍历右子树。
中序遍历在二叉搜索树的操作中非常常见,它可以按照从小到大的顺序输出二叉搜索树中的元素。
三、后序遍历后序遍历是指按照左子树、右子树、根节点的顺序访问二叉树的节点。
在后序遍历中,我们首先递归地遍历左子树和右子树,最后访问根节点。
后序遍历常用于对二叉树进行一些计算操作,比如计算二叉树的深度、判断二叉树是否对称等。
除了用于二叉树的遍历,先序、中序和后序还可以用来表示表达式的计算顺序。
在数学表达式中,运算符和操作数之间的顺序非常重要,它决定了表达式的计算结果。
先序、中序和后序可以用来表示运算符的位置,从而决定表达式的计算顺序。
先序表示法中,运算符位于操作数之前,如"+ 3 4"表示加法运算。
中序表示法中,运算符位于操作数之间,如"3 + 4"表示加法运算。
后序表示法中,运算符位于操作数之后,如"3 4 +"表示加法运算。
不同的表示法对应着不同的计算顺序,但它们都能得到相同的结果。
先序、中序和后序在数据结构中有着广泛的应用。
它们不仅仅是一种遍历方式,还可以表示表达式的计算顺序。
中国石油大学期末考试复习题 070109数据结构-18
《数据结构》综合复习资料一、填空题1、数据结构是()。
2、数据结构的四种基本形式为集合、()、()和()。
3、线性结构的基本特征是:若至少含有一个结点,则除起始结点没有直接前驱外,其他结点有且仅有一个直接();除终端结点没有直接()外,其它结点有且仅有一个直接()。
4、堆栈的特点是(),队列的特点是(),字符串中的数据元素为()。
5、字符串s1=“I am a student!”(单词与单词之间一个空格),s2=“student”,则字符串s1的长度为(),串s2是串s1的一个()串,串s2在s1中的位置为()。
6、KMP算法的特点:效率较();()回溯,对主串仅需要从头到尾扫描()遍,可以边读入边匹配。
7、广义表((a),((b),c),(((d))))的长度为(),表头为(),表尾为()。
8、ADT称为抽象数据类型,它是指()。
9、求下列程序的时间复杂度,并用大O表示方法表示()。
for( i=1 ; i<=n ; + + i)for( j=1 ; j<=i; + + j ){ ++x;a[i][j] = x;}10、以下运算实现在链栈上的退栈操作,请在_____处用适当句子予以填充。
int Pop(LstackTp *ls,DataType *x){ LstackTp *p;if(ls!=NULL){ p=ls;*x= ;ls= ;;return(1);}else return(0);}11、用堆栈求中缀表达式a+b*c/d+e*f的后缀表达式,求出的后缀表达式为()。
12、C语言中存储数组是采用以()为主序存储的,在C语言中定义二维数组float a[8][10],每个数据元素占4个字节,则数组共占用()字节的内存。
若第一个数据元素的存储地址为8000,则a[5][8]的存储地址为()。
13、含零个字符的串称为()串,用 表示。
其他串称为()串。
任何串中所含字符的个数称为该串的()。
二叉树的先序,中序,后序遍历c语言
二叉树的先序,中序,后序遍历c语言
二叉树是常见的数据结构,具有广泛的应用场景,例如搜索树、哈夫曼树等。
其中比较重要的一点就是对二叉树的遍历。
二叉树遍历有三种方式:先序遍历、中序遍历、后序遍历。
接下来,我将通过C语言来详细介绍这三种遍历方式。
一、先序遍历(Preorder Traversal)
先序遍历是指根节点->左子树->右子树的遍历方式。
C语言中的先序遍历算法如下:
```
void preorderTraversal(Node *node) {
if (node != NULL) {
printf("%d ", node->data); // 打印节点值
preorderTraversal(node->left); // 递归遍历左子树
preorderTraversal(node->right); // 递归遍历右子树
}
}
```
先序遍历的实现通过递归调用实现,当节点为空即遍历完成时返回。
总结:
以上三种遍历方式是二叉树遍历中最基本的方法,它们都是基于递归实现的。
通过学习这三种遍历方式,可以更好地理解二叉树的结构特点,提高数据结构算法的学习效果。
二叉树遍历(前中后序遍历,三种方式)
⼆叉树遍历(前中后序遍历,三种⽅式)⽬录刷题中碰到⼆叉树的遍历,就查找了⼆叉树遍历的⼏种思路,在此做个总结。
对应的LeetCode题⽬如下:,,,接下来以前序遍历来说明三种解法的思想,后⾯中序和后续直接给出代码。
⾸先定义⼆叉树的数据结构如下://Definition for a binary tree node.struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {}};前序遍历,顺序是“根-左-右”。
使⽤递归实现:递归的思想很简单就是我们每次访问根节点后就递归访问其左节点,左节点访问结束后再递归的访问右节点。
代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;helper(root,res);return res;}void helper(TreeNode *root, vector<int> &res){res.push_back(root->val);if(root->left) helper(root->left, res);if(root->right) helper(root->right, res);}};使⽤辅助栈迭代实现:算法为:先把根节点push到辅助栈中,然后循环检测栈是否为空,若不空,则取出栈顶元素,保存值到vector中,之后由于需要想访问左⼦节点,所以我们在将根节点的⼦节点⼊栈时要先经右节点⼊栈,再将左节点⼊栈,这样出栈时就会先判断左⼦节点。
代码如下:class Solution {public:vector<int> preorderTraversal(TreeNode* root) {if(root == NULL) return {};vector<int> res;stack<TreeNode*> st;st.push(root);while(!st.empty()){//将根节点出栈放⼊结果集中TreeNode *t = st.top();st.pop();res.push_back(t->val);//先⼊栈右节点,后左节点if(t->right) st.push(t->right);if(t->left) st.push(t->left);}return res;}};Morris Traversal⽅法具体的详细解释可以参考如下链接:这种解法可以实现O(N)的时间复杂度和O(1)的空间复杂度。
c语言二叉树的先序,中序,后序遍历
c语言二叉树的先序,中序,后序遍历1、先序遍历先序遍历可以想象为,一个小人从一棵二叉树根节点为起点,沿着二叉树外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果先序遍历结果为:A B D H I E J C F K G2、中序遍历中序遍历可以看成,二叉树每个节点,垂直方向投影下来(可以理解为每个节点从最左边开始垂直掉到地上),然后从左往右数,得出的结果便是中序遍历的结果中遍历结果为:H D I B E J A F K C G3、后序遍历后序遍历就像是剪葡萄,我们要把一串葡萄剪成一颗一颗的。
还记得我上面提到先序遍历绕圈的路线么?(不记得翻上面理解)就是围着树的外围绕一圈,如果发现一剪刀就能剪下的葡萄(必须是一颗葡萄)(也就是葡萄要一个一个掉下来,不能一口气掉超过1个这样),就把它剪下来,组成的就是后序遍历了。
后序遍历中,根节点默认最后面后序遍历结果:H I D J E B K F G C A4、口诀先序遍历:先根再左再右中序遍历:先左再根再右后序遍历:先左再右再根这里的根,指的是每个分叉子树(左右子树的根节点)根节点,并不只是最开始头顶的根节点,需要灵活思考理解5、代码展示#include<stdio.h>#include<stdlib.h>typedef struct Tree{int data; // 存放数据域struct Tree *lchild; // 遍历左子树指针struct Tree *rchild; // 遍历右子树指针}Tree,*BitTree;BitTree CreateLink(){int data;int temp;BitTree T;scanf("%d",&data); // 输入数据temp=getchar(); // 吸收空格if(data == -1){ // 输入-1 代表此节点下子树不存数据,也就是不继续递归创建return NULL;}else{T = (BitTree)malloc(sizeof(Tree)); // 分配内存空间T->data = data; // 把当前输入的数据存入当前节点指针的数据域中printf("请输入%d的左子树: ",data);T->lchild = CreateLink(); // 开始递归创建左子树printf("请输入%d的右子树: ",data);T->rchild = CreateLink(); // 开始到上一级节点的右边递归创建左右子树return T; // 返回根节点}}// 先序遍历void ShowXianXu(BitTree T) // 先序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}printf("%d ",T->data);ShowXianXu(T->lchild); // 递归遍历左子树ShowXianXu(T->rchild); // 递归遍历右子树}// 中序遍历void ShowZhongXu(BitTree T) // 先序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}ShowZhongXu(T->lchild); // 递归遍历左子树printf("%d ",T->data);ShowZhongXu(T->rchild); // 递归遍历右子树}// 后序遍历void ShowHouXu(BitTree T) // 后序遍历二叉树{if(T==NULL) //递归中遇到NULL,返回上一层节点{return;}ShowHouXu(T->lchild); // 递归遍历左子树ShowHouXu(T->rchild); // 递归遍历右子树printf("%d ",T->data);}int main(){BitTree S;printf("请输入第一个节点的数据:\n");S = CreateLink(); // 接受创建二叉树完成的根节点printf("先序遍历结果: \n");ShowXianXu(S); // 先序遍历二叉树printf("\n中序遍历结果: \n");ShowZhongXu(S); // 中序遍历二叉树printf("\n后序遍历结果: \n");ShowHouXu(S); // 后序遍历二叉树return 0;}。
前序后序中序详细讲解
前序后序中序详细讲解1.引言1.1 概述在数据结构与算法中,前序、中序和后序是遍历二叉树的三种基本方式之一。
它们是一种递归和迭代算法,用于按照特定的顺序访问二叉树的所有节点。
通过遍历二叉树,我们可以获取有关树的结构和节点之间关系的重要信息。
前序遍历是指先访问根节点,然后递归地访问左子树,最后递归地访问右子树。
中序遍历是指先递归地访问左子树,然后访问根节点,最后递归地访问右子树。
后序遍历是指先递归地访问左子树,然后递归地访问右子树,最后访问根节点。
它们的不同之处在于访问根节点的时机不同。
前序遍历可以帮助我们构建二叉树的镜像,查找特定节点,或者获取树的深度等信息。
中序遍历可以帮助我们按照节点的大小顺序输出树的节点,或者查找二叉搜索树中的某个节点。
后序遍历常用于删除二叉树或者释放二叉树的内存空间。
在实际应用中,前序、中序和后序遍历算法有着广泛的应用。
它们可以用于解决树相关的问题,例如在Web开发中,树结构的遍历算法可以用于生成网页导航栏或者搜索树结构中的某个节点。
在图像处理中,前序遍历可以用于图像压缩或者图像识别。
另外,前序和后序遍历算法还可以用于表达式求值和编译原理中的语法分析等领域。
综上所述,前序、中序和后序遍历算法是遍历二叉树的重要方式,它们在解决各种与树有关的问题中扮演着关键的角色。
通过深入理解和应用这些遍历算法,我们可以更好地理解和利用二叉树的结构特性,并且能够解决更加复杂的问题。
1.2文章结构文章结构是指文章中各个部分的布局和组织方式。
一个良好的文章结构可以使读者更好地理解和理解文章的内容。
本文将详细讲解前序、中序和后序三个部分的内容和应用。
首先,本文将在引言部分概述整篇文章的内容,并介绍文章的结构和目的。
接下来,正文部分将分为三个小节,分别对前序、中序和后序进行详细讲解。
在前序讲解部分,我们将定义和解释前序的意义,并介绍前序在实际应用中的场景。
通过详细的解释和实例,读者将能更好地理解前序的概念和用途。
数据结构_二叉树的遍历_课程设计
8
if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } } void postorder(bitree *bt)/*后序序遍历二叉树*/ { if(bt!=NULL) { postorder(bt->lchild); postorder(bt->rchild); printf("%c",bt->data); } }
3.2.2 二叉树的中序递归遍历算法
void inorder(bitree *bt)/*中序序遍历二叉树*/ { if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } }
图 1 “菜单”界面
图2
创建二叉树
5
图 3 二叉树的先序遍历
图4
二叉树的中序输出
6
图 5 二叉树的后序输出
五:实验总结 虽然做的过程中出现很多错误。但是最后还是一一纠正了,并在其中发现了自 身的不足,补学补差。最后终于完成了。
六:源程序附录
#include<stdio.h> #include<stdlib.h> typedef char datatype; typedef struct node { datatype data;/*数据元素*/ struct node *lchild,*rchild;/*指向左,右孩子*/ }bitree; bitree *root;/*二叉树结点类型定义*/ bitree *creatbitree(bitree *root)/*创建二叉树*/ { char ch;
前序遍历中序遍历复原方法
前序遍历中序遍历复原方法树是一种非线性的数据结构,它的一个重要性质就是可以通过不同的遍历顺序来表达树的结构。
在二叉树中,常用的三种遍历方式有前序遍历、中序遍历和后序遍历。
这三种遍历方式可以帮助我们了解树的结构,从而实现一些操作,比如复原树的结构。
在本文中,我们将讨论如何通过前序遍历和中序遍历的结果来复原一棵树的结构。
前序遍历、中序遍历和后序遍历是树的三种深度优先遍历方式。
它们的定义如下:-前序遍历:先访问根节点,再依次遍历左子树和右子树。
-中序遍历:先遍历左子树,再访问根节点,最后遍历右子树。
-后序遍历:先遍历左子树,再遍历右子树,最后访问根节点。
在这三种遍历方式中,前序遍历和中序遍历是最常用的。
在实际应用中,有时我们只能得到树的前序遍历和中序遍历结果,但想要还原树的结构。
那么,该如何通过前序遍历和中序遍历的结果来复原一棵树的结构呢?为了解决这个问题,我们首先需要知道前序遍历和中序遍历的性质。
在前序遍历中,第一个元素一定是根节点,在中序遍历中,根节点左边的元素都位于左子树中,根节点右边的元素都位于右子树中。
利用这些性质,我们可以进行如下步骤来复原树的结构:1.根据前序遍历的结果确定根节点。
2.在中序遍历的结果中找到根节点的位置,划分出左子树和右子树。
3.递归处理左子树和右子树,直到无法再继续递归。
下面,我们以一个具体的例子来说明如何通过前序遍历和中序遍历的结果来复原一棵树的结构。
假设我们有以下一棵树的前序遍历结果为[1,2,4,5,3,6,7],中序遍历结果为[4,2,5,1,6,3,7]。
我们需要还原这棵树的结构。
首先,根据前序遍历的结果,我们可以知道根节点是1、然后,在中序遍历的结果中找到根节点1的位置,左子树为[4,2,5],右子树为[6,3,7]。
接下来,我们递归处理左子树和右子树。
对于左子树,前序遍历结果为[2,4,5],中序遍历结果为[4,2,5]。
根据前序遍历的结果,我们可以知道左子树的根节点是2、在中序遍历的结果中找到根节点2的位置,左子树为空,右子树为[4,5]。
二叉树的各种算法
二叉树的各种算法1.二叉树的前序遍历算法:前序遍历是指先访问根节点,再访问左子树,最后访问右子树的遍历顺序。
具体算法如下:-如果二叉树为空,则直接返回。
-访问根节点,并输出或进行其他操作。
-递归地前序遍历左子树。
-递归地前序遍历右子树。
2.二叉树的中序遍历算法:中序遍历是指先访问左子树,再访问根节点,最后访问右子树的遍历顺序。
具体算法如下:-如果二叉树为空,则直接返回。
-递归地中序遍历左子树。
-访问根节点,并输出或进行其他操作。
-递归地中序遍历右子树。
3.二叉树的后序遍历算法:后序遍历是指先访问左子树,再访问右子树,最后访问根节点的遍历顺序。
具体算法如下:-如果二叉树为空,则直接返回。
-递归地后序遍历左子树。
-递归地后序遍历右子树。
-访问根节点,并输出或进行其他操作。
4.二叉树的层序遍历算法:层序遍历是按照从上到下、从左到右的顺序逐层遍历二叉树的节点。
具体算法如下:-如果二叉树为空,则直接返回。
-创建一个队列,将根节点入队。
-循环执行以下步骤,直到队列为空:-出队并访问当前节点,并输出或进行其他操作。
-若当前节点的左子节点不为空,则将左子节点入队。
-若当前节点的右子节点不为空,则将右子节点入队。
5.二叉树的深度算法:二叉树的深度是指从根节点到叶节点的最长路径的节点数。
具体算法如下:-如果二叉树为空,则深度为0。
-否则,递归地计算左子树的深度和右子树的深度,然后取较大的值加上根节点的深度作为二叉树的深度。
6.二叉树的查找算法:二叉树的查找可以使用前序、中序或后序遍历来完成。
具体算法如下:-如果二叉树为空,则返回空。
-如果当前节点的值等于目标值,则返回当前节点。
-否则,先在左子树中递归查找,如果找到则返回找到的节点。
-如果左子树中未找到,则在右子树中递归查找,如果找到则返回找到的节点。
-如果左右子树中都未找到,则返回空。
7.二叉树的插入算法:二叉树的插入可以使用递归或循环来实现。
具体算法如下:-如果二叉树为空,则创建一个新节点作为根节点,并返回根节点。
c++实现树(二叉树)的建立和遍历算法(一)(前序,中序,后序)
c++实现树(⼆叉树)的建⽴和遍历算法(⼀)(前序,中序,后序)最近学习树的概念,有关⼆叉树的实现算法记录下来。
不过学习之前要了解的预备知识:树的概念;⼆叉树的存储结构;⼆叉树的遍历⽅法。
⼆叉树的存储结构主要了解⼆叉链表结构,也就是⼀个数据域,两个指针域,(分别为指向左右孩⼦的指针),从下⾯程序1,⼆叉树的存储结构可以看出。
⼆叉树的遍历⽅法:主要有前序遍历,中序遍历,后序遍历,层序遍历。
(层序遍历下⼀篇再讲,本篇主要讲的递归法)下篇主要是,之后会有c++模板实现和。
如这样⼀个⼆叉树:它的前序遍历顺序为:ABDGHCEIF(规则是先是根结点,再前序遍历左⼦树,再前序遍历右⼦树)它的中序遍历顺序为:GDHBAEICF(规则是先中序遍历左⼦树,再是根结点,再是中序遍历右⼦树)它的后序遍历顺序为:GHDBIEFCA(规则是先后序遍历左⼦树,再是后序遍历右⼦树,再是根结点)如果不懂的话,可以参看有关数据结构的书籍。
1,⼆叉树的存储结构(⼆叉链表)//⼆叉树的⼆叉链表结构,也就是⼆叉树的存储结构,1个数据域,2个指针域(分别指向左右孩⼦)typedef struct BiTNode{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree;2,⾸先要建⽴⼀个⼆叉树,建⽴⼆叉树必须要了解⼆叉树的遍历⽅法。
//⼆叉树的建⽴,按前序遍历的⽅式建⽴⼆叉树,当然也可以以中序或后序的⽅式建⽴⼆叉树void CreateBiTree(BiTree *T){ElemType ch;cin >> ch;if (ch == '#')*T = NULL; //保证是叶结点else{*T = (BiTree)malloc(sizeof(BiTNode));//if (!*T)//exit(OVERFLOW); //内存分配失败则退出。
二叉树的先中后序遍历及相关常用算法
#include <string.h>#include <stdlib.h>typedef char T;int i=0; //叶子结点数typedef struct btnode //结点定义{T Element;struct btnode *LChild,*RChild;}BTNode;typedef struct btree //头结点定义{struct btnode *Root;}BTree;BTNode* NewNode() //创建空间{BTNode *p=(BTNode*)malloc(sizeof(BTNode));return p;}void CreateBT(BTree *Bt) //创建一棵空二叉树{Bt->Root=NULL;}void MakeBT(BTree *Bt,T x,BTree *Lt,BTree *Rt) //进行树的建立{BTNode *p=NewNode();p->Element=x;p->LChild=Lt->Root;p->RChild=Rt->Root;Lt->Root=Rt->Root=NULL;Bt->Root=p;}void Visit(BTNode *p) //输出结点*P的元素值{printf("%c",p->Element);}void PreOrd(void(*Visit)(BTNode *u),BTNode *t) //先序遍历递归函数{if(t){(*Visit)(t);PreOrd(Visit,t->LChild);PreOrd(Visit,t->RChild);}}void InOrd(void(*Visit)(BTNode *u),BTNode *t) //中序遍历递归函数{if(t){InOrd(Visit,t->LChild);(*Visit)(t);InOrd(Visit,t->RChild);}}void PostOrd(void(*Visit)(BTNode *u),BTNode *t) //后序遍历递归函数{if(t){PostOrd(Visit,t->LChild);PostOrd(Visit,t->RChild);(*Visit)(t);}}void PreOrder(BTree Bt,void (*Visit)(BTNode *u)) //先序遍历{PreOrd(Visit,Bt.Root);}void InOrder(BTree Bt,void (*Visit)(BTNode *u)) //中序遍历{InOrd(Visit,Bt.Root);}void PostOrder(BTree Bt,void (*Visit)(BTNode *u)) //后序遍历{PostOrd(Visit,Bt.Root);}int Size(BTNode *p) //树的结点数与叶子结点数的递归函数{int s,s1,s2;if(!p)return 0;else{s1=Size(p->LChild);s2=Size(p->RChild);s=s1+s2+1;if(s1==0&&s2==0)//判断是否是叶子节点{i++;printf("%3c",p->Element);return s;}else{return s;}}}int SizeofBT(BTree Bt) //树的结点数{return Size(Bt.Root);}int Depth(BTNode *p) //树的高度递归函数{if(!p)return 0;elsereturn 1+max(Depth(p->LChild),Depth(p->RChild));}int DepthofBT(BTree Bt) //树的高度{return Depth(Bt.Root);}void BreakBT(BTree* Bt,T *x,BTree *Lt,BTree *Rt) //树的拆分{BTNode *p=Bt->Root;if(p){x=p->Element;printf("根数:%c\n",x);Lt->Root =p->LChild;Rt->Root =p->RChild;Bt->Root=NULL;free(p);}}void main(void){BTree a,x,y,z;T e; //树的结点的元素int j,k; //树的结点数与高度CreateBT(&a);CreateBT(&x);CreateBT(&y);CreateBT(&z); //建立空树MakeBT(&x,'B',&a,&a);MakeBT(&x,'A',&x,&z);printf("遍历算法测试:\n");printf("---------------------------------------\n");printf("先序遍历测试结果:");PreOrder(x,Visit);printf("\n中序遍历测试结果:");InOrder(x,Visit);printf("\n后序遍历测试结果:");PostOrder(x,Visit);printf("\n树的叶子结点为:");//建立树j=SizeofBT(x);k=DepthofBT(x);printf("\n树的叶子结点数为:%d\n",i);printf("树的结点数为:%d\n",j);printf("树的高度为:%d\n\n\n",k);printf("拆树算法测试:\n");printf("---------------------------------------\n");BreakBT(&x,&e,&z,&y);printf("---------------------------------------\n");printf("左孩子:\n");printf("先序遍历测试结果:");PreOrder(z,Visit);printf("\n中序遍历测试结果:");InOrder(z,Visit);printf("\n后序遍历测试结果:");PostOrder(z,Visit);i=0;printf("\n树的叶子结点为:");//建立树j=SizeofBT(z);k=DepthofBT(z);printf("\n树的叶子结点数为:%d\n",i);printf("树的结点数为:%d\n",j);printf("树的高度为:%d\n\n\n",k);printf("---------------------------------------\n");printf("右孩子:\n");printf("先序遍历测试结果:");PreOrder(y,Visit);printf("\n中序遍历测试结果:");InOrder(y,Visit);printf("\n后序遍历测试结果:");PostOrder(y,Visit);i=0;printf("\n树的叶子结点为:");//建立树j=SizeofBT(y);k=DepthofBT(y);printf("\n树的叶子结点数为:%d\n",i);printf("树的结点数为:%d\n",j);printf("树的高度为:%d\n\n\n",k);printf("\n");}。
C语言实现二叉树的中序遍历(递归)
C语 言 实 现 二 叉 树 的 中 序 遍 历 ( 递 归 )
二叉树的前序遍历、中序遍历、后续遍历 (包括递归、非递归,共六种) 1、中序遍历(递归): #include #include struct BiTNode//定义结构体 { char data; struct BiTNode *lchild,*rchild; }; void later(struct BiTNode *&p) //前序创建树 { char ch; scanf("%c",&ch); if(ch==' ') p=NULL; else { p=(struct BiTNode *)malloc(sizeof(struct BiTNode)); p->data=ch; later(p->lchild); later(p->rchild); } } void print(struct BiTNode *p) //中序遍历(输出二叉树) { if(p!=NULL) { print(p->lchild); printf("%c",p->data); print(p->rchild); } else printf(" ");
二叉树的四种遍历算法
⼆叉树的四种遍历算法⼆叉树作为⼀种重要的数据结构,它的很多算法的思想在很多地⽅都⽤到了,⽐如STL算法模板,⾥⾯的优先队列、集合等等都⽤到了⼆叉树⾥⾯的思想,先从⼆叉树的遍历开始:看⼆叉树长什么样⼦:我们可以看到这颗⼆叉树⼀共有七个节点0号节点是根节点1号节点和2号节点是0号节点的⼦节点,1号节点为0号节点的左⼦节点,2号节点为0号节点的右⼦节点同时1号节点和2号节点⼜是3号节点、四号节点和五号节点、6号节点的双亲节点五号节点和6号节点没有⼦节点(⼦树),那么他们被称为‘叶⼦节点’这就是⼀些基本的概念⼆叉树的遍历⼆叉树常⽤的遍历⽅式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历⽅式,不同的遍历算法,其思想略有不同,我们来看⼀下这四种遍历⽅法主要的算法思想:1、先序遍历⼆叉树顺序:根节点 –> 左⼦树 –> 右⼦树,即先访问根节点,然后是左⼦树,最后是右⼦树。
上图中⼆叉树的前序遍历结果为:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 62、中序遍历⼆叉树顺序:左⼦树 –> 根节点 –> 右⼦树,即先访问左⼦树,然后是根节点,最后是右⼦树。
上图中⼆叉树的中序遍历结果为:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 63、后续遍历⼆叉树顺序:左⼦树 –> 右⼦树 –> 根节点,即先访问左⼦树,然后是右⼦树,最后是根节点。
上图中⼆叉树的后序遍历结果为:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 04、层序遍历⼆叉树顺序:从最顶层的节点开始,从左往右依次遍历,之后转到第⼆层,继续从左往右遍历,持续循环,直到所有节点都遍历完成上图中⼆叉树的层序遍历结果为:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6下⾯是四种算法的伪代码:前序遍历:preOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束cout << tree[n].w ; // 输出当前节点内容preOrderParse(tree[n].leftChild); // 递归输出左⼦树preOrderParse(tree[n].rightChild); // 递归输出右⼦树}中序遍历inOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束inOrderParse(tree[n].leftChild); // 递归输出左⼦树cout << tree[n].w ; // 输出当前节点内容inOrderParse(tree[n].rightChild); // 递归输出右⼦树}pastOrderParse(int n) {if(tree[n] == NULL)return ; // 如果这个节点不存在,那么结束pastOrderParse(tree[n].leftChild); // 递归输出左⼦树pastOrderParse(tree[n].rightChild); // 递归输出右⼦树cout << tree[n].w ; // 输出当前节点内容}可以看到前三种遍历都是直接通过递归来完成,⽤递归遍历⼆叉树简答⽅便⽽且好理解,接下来层序遍历就需要动点脑筋了,我们如何将⼆叉树⼀层⼀层的遍历输出?其实在这⾥我们要借助⼀种数据结构来完成:队列。
先序中序后序遍历算法
先序中序后序遍历算法
先序、中序和后序遍历是二叉树遍历的三种基本方法,它们可以帮助我们按照不同顺序访问树中的节点。
下面我会分别介绍这三种遍历算法。
1. 先序遍历:
先序遍历是指先访问根节点,然后递归地对左子树进行先序遍历,最后递归地对右子树进行先序遍历。
因此,先序遍历的顺序是根-左-右。
2. 中序遍历:
中序遍历是指先递归地对左子树进行中序遍历,然后访问根节点,最后递归地对右子树进行中序遍历。
因此,中序遍历的顺序是左-根-右。
3. 后序遍历:
后序遍历是指先递归地对左子树进行后序遍历,然后递归地
对右子树进行后序遍历,最后访问根节点。
因此,后序遍历的顺序
是左-右-根。
这三种遍历算法都是基于递归的思想实现的,它们在不同的应
用场景下都有各自的优势。
例如,先序遍历常用于复制整棵树,中
序遍历常用于二叉搜索树的查找操作,后序遍历常用于计算表达式
树的值等。
除了递归实现外,这三种遍历算法也可以通过迭代的方式实现,通常使用栈来辅助实现。
在实际应用中,根据具体的问题和数据结
构的特点,选择合适的遍历算法可以提高算法的效率和准确性。
总之,先序、中序和后序遍历算法是树结构中常用的基本算法,它们在数据结构和算法领域具有重要的意义,对于理解树的结构和
实现树相关的操作非常重要。
希望以上介绍能够帮助你更好地理解
这三种遍历算法。
C++二叉树的先序,中序,后序遍历
C++⼆叉树的先序,中序,后序遍历三种遍历⽅式都分为递归与⾮递归的⽅式。
三种遍历⽅式的递归思想相同。
后序遍历⾮递归⽅法分为两种,具体见代码。
构造⽅式:1 #include<iostream>2 #include<stack>3using namespace std;45 typedef struct BiTNode{6char data;7int lvisited,rvisited;//左、右孩⼦是否访问过,1表⽰已访问(此项只在后序⾮递归2算法中需要)8struct BiTNode *lchild,*rchild;9 }BiTNode,*BiTree;1011void InitBiTree(BiTree &T)//构造空⼆叉树12 {13 T=NULL;14 }15void CreateBiTree(BiTree &T)//⽣成⼆叉树16 {17char ch;18 cin>>ch;19if(ch=='0')//0代表空20 T=NULL;21else22 {23 T=(BiTree)malloc(sizeof(BiTNode));//⽣成根结点24if(!T)25 {26 cout<<"⽣成结点错误!"<<endl;27return;28 }29 T->data=ch;30 T->lvisited=0;31 T->rvisited=0;32 CreateBiTree(T->lchild);33 CreateBiTree(T->rchild);34 }35 }三种遍历⽅式代码:1void PreOrder(BiTree T)//先序递归遍历2 {3if(T!=NULL)4 {5 cout<<T->data<<"";6 PreOrder(T->lchild);7 PreOrder(T->rchild);8 }9 }10void SqlPreOrder(BiTree T)//先序⾮递归遍历11 {12 stack<BiTree> s;13 BiTree p=T;14while(p || !s.empty())15 {16if(p)17 {18 cout<<p->data<<"";19 s.push(p);20 p=p->lchild;21 }22else23 {24 p=s.top();25 p=p->rchild;26 s.pop();27 }28 }29 }30313233void InOrder(BiTree T)//中序递归遍历34 {35if(T!=NULL)36 {37 InOrder(T->lchild);38 cout<<T->data<<"";39 InOrder(T->rchild);40 }41 }42void SqInOrder(BiTree T)//中序⾮递归遍历43 {44 stack<BiTree> s;45 BiTree p=T;46while(p || !s.empty())47if(p)48 {49 s.push(p);50 p=p->lchild;51 }52else53 {54 p=s.top();55 cout<<p->data<<"";56 s.pop();57 p=p->rchild;58 }59 }60616263void PostOrder(BiTree T)//后序递归遍历64 {65if(T!=NULL)66 {67 PostOrder(T->lchild);68 PostOrder(T->rchild);69 cout<<T->data<<"";70 }71 }7273//后序⾮递归遍历1思路:因为后序⾮递归遍历⼆叉树的顺序是先访问左⼦树,再访问后⼦树,最后 74//访问根结点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <iostream>
using namespace std;
#define queuesize 100
#define ERROR 0
#define OK 1
typedef struct BiTNode//二叉树
{
char data;
struct BiTNode *lchild,*rchild;
}BinNode;
typedef BinNode * BiTree;//定义二叉链表指针类型
typedef struct
{
int front,rear;
BiTree data[queuesize];//循环队列元素类型为二叉链表结点指针
int count;
}cirqueue;//循环队列结构定义
void leverorder(BiTree t)
{
cirqueue *q;
BiTree p;
q=new cirqueue;//申请循环队列空间
q->rear=q->front=q->count=0;//将循环队列初始化为空
q->data[q->rear]=t;q->count++;q->rear=(q->rear+1)%queuesize;//将根结点入队
while (q->count) //若队列不为空,做以下操作
if (q->data[q->front]) //当队首元素不为空指针,做以下操作
{
p=q->data[q->front]; //取队首元素*p
cout<<p->data;
q->front=(q->front+1)%queuesize;q->count--;//队首元素出队
if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行cout<<"error,队列满了!";
else
{//若队列不满,将*p结点的左孩子指针入队
q->count++;q->data[q->rear]=p->lchild;
q->rear=(q->rear+1)%queuesize;
}
if (q->count==queuesize)//若队列为队满,则打印队满信息,退出程序的执行cout<<"error";
else
{//若队列不满,将*p结点的右孩子指针入队
q->count++;q->data[q->rear]=p->rchild;
q->rear=(q->rear+1)%queuesize;
}
}
else
{q->front=(q->front+1)%queuesize;q->count--;}//当队首元素为空指针,将空指针出队}
int CreatBiTree(BiTree& root)
{
char ch;
BiTree p;
BiTree q[100];
int front=1,rear=0;
int jj=0;
ch=getchar();
while(ch!='#')
{
p=NULL;
if(ch!=',')
{
p=(BiTNode*)malloc(sizeof(BiTNode));
if(NULL==p)
return ERROR;
jj++;
p->data=ch;
p->lchild=p->rchild=NULL;
}
rear++;
q[rear]=p;
if(1==rear)
root=p;
else
{
if(p&&q[front])
{
if(0==(rear%2))
q[front]->lchild=p;
else
q[front]->rchild=p;
}
if(p&&(NULL==q[front]))
{
free(p);
return ERROR;
}
if(1==rear%2)
front++;
}
ch=getchar();
}
return OK;
}
void PreOrder(BiTree root) //先序遍历
{
if(root!=NULL)
{
cout<<root->data; //根
PreOrder(root->lchild);//左
PreOrder(root->rchild);//右
}
}
void InOrder(BiTree root) //中序遍历
{
if(root!=NULL)
{
InOrder(root->lchild); //左
cout<<root->data; //根
InOrder(root->rchild); //右
}
}
void PostOrder(BiTree root) //后序遍历
{
if(root!=NULL)
{
PostOrder(root->lchild);//左
PostOrder(root->rchild);//右
cout<<root->data; //根
}
}
int shuru()
{cout<<"输入二叉树(,表示空)安#结束输入:\n";}
int main()
{
shuru();
BiTree ss;
int i=CreatBiTree(ss);
cout<<endl<<"先序遍历二叉树:";
PreOrder(ss);
cout<<endl<<"中序遍历二叉树:";
InOrder(ss);
cout<<endl<<"后序遍历二叉树:";
PostOrder(ss);
cout<<endl<<"层序遍历二叉树:";
leverorder(ss);
cout<<endl;
return 0;
}
程序结果:。