二叉树知道前序和中序求后序,知道中序后序求中序

article/2025/9/17 17:22:15

今天来总结下二叉树前序、中序、后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明。

首先,我们看看前序、中序、后序遍历的特性: 
前序遍历: 
    1.访问根节点 
    2.前序遍历左子树 
    3.前序遍历右子树 
中序遍历: 
    1.中序遍历左子树 
    2.访问根节点 
    3.中序遍历右子树 
后序遍历: 
    1.后序遍历左子树 
    2.后序遍历右子树 
    3.访问根节点

一、已知前序、中序遍历,求后序遍历

例:

前序遍历:         GDAFEMHZ

中序遍历:         ADEFGHMZ

画树求法:
第一步,根据前序遍历的特点,我们知道根结点为G

第二步,观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。

 第三步,观察左子树ADEF,左子树的中的根节点必然是大树的root的leftchild。在前序遍历中,大树的root的leftchild位于root之后,所以左子树的根节点为D。

第四步,同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把root和root的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。

第五步,观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:

1 确定根,确定左子树,确定右子树。

2 在左子树中递归。

3 在右子树中递归。

4 打印当前根。

那么,我们可以画出这个二叉树的形状:

那么,根据后序的遍历规则,我们可以知道,后序遍历顺序为:AEFDHZMG

 

#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
typedef struct node
{char data;struct node *leftchild;struct node *rightchild;
} bitreenode,*bitree;
//*preorders是先序的字符串,inorder是中序的字符串
void posttraverse(char *preorder,char *inorder,int len)//求后序
{if(len==0)return ;int rootindex=0;node newnode;newnode.data=preorder[0];//先序字符串的首元素是根节点for(rootindex=0; preorder[0]!=inorder[rootindex]; rootindex++);//这一步是找到根节点在中序字符串中的位置posttraverse(preorder+1,inorder,rootindex);//递归遍历左子树posttraverse(preorder+rootindex+1,inorder+rootindex+1,len-rootindex-1);//递归遍历右子树cout<<*preorder;//打印根节点,为什么要放在最后呢?因为这是求后序遍历,如果是求先序遍历//就在递归之前打印根节点
}
void pretraverse(char *inorder,char *postorder,int len)//求先序
{//类似知先序和中序求后序if(len==0)return ;int rootindex=0;node newnode;newnode.data=postorder[len-1];cout<<postorder[len-1];for(rootindex=0; postorder[len-1]!=inorder[rootindex]; rootindex++);pretraverse(inorder,postorder,rootindex);pretraverse(inorder+rootindex+1,postorder+rootindex,len-rootindex-1);
}/*node* BinaryTreeFromOrderings(char* inorder, char* aftorder, int length)//求先序,同时建树
{if(length == 0){return NULL;}node* Node = new node;//Noice that [new] should be written out.Node->data= *(aftorder+length-1);cout<<Node->data;int rootIndex = 0;for(;rootIndex < length; rootIndex++)//a variation of the loop{if(inorder[rootIndex] ==  *(aftorder+length-1))break;}Node->leftchild = BinaryTreeFromOrderings(inorder, aftorder , rootIndex);Node->rightchild= BinaryTreeFromOrderings(inorder + rootIndex + 1, aftorder + rootIndex , length - (rootIndex + 1));return Node;
}*/
int main()
{int i,j,k,cur,last;char s1[1000],s2[1000];while(scanf("%s",s1)!=EOF){scanf("%s",s2);//posttraverse(s1,s2,strlen(s1));pretraverse(s1,s2,strlen(s1));//BinaryTreeFromOrderings(s1,s2,strlen(s1));cout<<endl;}/*GDAFEMHZADEFGHMZ前一个是先序,后一个是中序*///结果AEFDHZMG/*ADEFGHMZAEFDHZMG前一个是中序,后一个是后序*///结果GDAFEMHZreturn 0;
}
AEFDHZMG/*ADEFGHMZAEFDHZMG前一个是中序,后一个是后序*///结果GDAFEMHZreturn 0;
}

 

 

 

二、已知中序和后序遍历,求前序遍历

依然是上面的题,这次我们只给出中序和后序遍历:

中序遍历:       ADEFGHMZ

后序遍历:       AEFDHZMG

画树求法:
第一步、根据后序遍历的特点,我们知道后序遍历最后一个结点即为根结点,即根结点为G。

第二步、观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。

第三步、观察左子树中序为ADEF,后序AEFD,根据第一步即可判断根节点为D。观察右子树中序HMZ,后序HZM,可以确定根节点为M。

第四步、观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:

1 确定根,确定左子树,确定右子树。

2 在左子树中递归。

3 在右子树中递归。

4 打印当前根。

这样,我们就可以画出二叉树的形状,如上图所示,这里就不再赘述。

那么,前序遍历:         GDAFEMHZ

具体程序代码已在在上个代码中给出

现在咱们具体来分析下以下语句:

void pretraverse(char *inorder,char *postorder,int len)//求先序
{//类似知先序和中序求后序if(len==0)return ;int rootindex=0;node newnode;newnode.data=postorder[len-1];cout<<postorder[len-1];for(rootindex=0; postorder[len-1]!=inorder[rootindex]; rootindex++);pretraverse(inorder,postorder,rootindex);pretraverse(inorder+rootindex+1,postorder+rootindex,len-rootindex-1);
}

rootindex是根节点的位置,用它来表示左子树和右子树在字符串中的长度

preorder+1是先序左子树开始的位置,inorder的人是中序左子树开始的位置,rootindex是左子树长度

preorder+rootindex+1是右子树开始的位置,同理inorder+rootindex+1是中序串右子树开始的位置,len-rootindex-1是长度

要特别注意子树开始的位置,不能弄错了:如pretraverse(inorder,postorder,rootindex);

 

pretraverse(inorder+rootindex+1,postorder+rootindex,len-rootindex-1);后序字符串中右子树开始的位置是postorder+rootindex,不是postorder+index+1!!!!!!

 

 

 

 


http://chatgpt.dhexx.cn/article/vb6pHIsM.shtml

相关文章

二叉树的前序、中序和后序遍历(Java实现)

文章目录 前言1. 中左右进行遍历&#xff1a;2. 代码实现 二、中序1. 左中右进行遍历2. 代码实现 三、后序1. 左右中进行遍历2. 代码实现 四、逆推二叉树 前言 二叉树一遍有前序、中序和后序三种遍历方式&#xff0c;不同的遍历方式有不同的用处。 二叉树遍历都是先左后右的。…

二叉树的先序,中序,后序遍历序列

二叉树有三种遍历&#xff1a; 1. 先序遍历&#xff1a; &#xff08;根左右&#xff09; 2.中序遍历 &#xff1a; &#xff08;左根右&#xff09; 3.后序遍历&#xff1a; &#xff08;左右根&#xff09; 举个例子&#xff1a;&#xff08;以下动画图转载自https://blo…

如何判断二叉树的前序,中序,后序遍历

文章目录 前言一、如何判断二叉树的前序&#xff0c;中序&#xff0c;后序遍历&#xff1f;二、已知二叉树的前序遍历和中序遍历&#xff0c;如何得到它的后序遍历&#xff1f;三、程序实现总结 前言 最近复习题中看到二叉树&#xff0c;对于它的前序&#xff0c;中序&#xf…

关于二叉树的前序、中序、后序三种遍历

二叉树遍历分为三种&#xff1a;前序、中序、后序&#xff0c;其中序遍历最为重要。为啥叫这个名字&#xff1f;是根据根节点的顺序命名的。 比如上图正常的一个满节点&#xff0c;A&#xff1a;根节点、B&#xff1a;左节点、C&#xff1a;右节点&#xff0c;前序顺序是ABC&a…

二叉树顺序存储之 前序,中序 ,后序遍历

二叉树遍历的概念&#xff1a; 二叉树的遍历是指从根结点出发&#xff0c;按照某种次序依次访问二叉树中的所有结点&#xff0c;使得每个结点被访问一次且仅被访问一次。 1、前序遍历 先输出当前结点的数据&#xff0c;再依次遍历输出左结点和右结点 如下图二叉树分析&#…

二叉树的前序、中序和后序遍历

目录 文章目录 目录前言一、二叉树遍历是什么&#xff1f;二、二叉树遍历的种类 1.前序遍历2.中序遍历3.后序遍历总结 前言 例如&#xff1a;跟着其他的大神学习了二叉树的遍历&#xff0c;下面简单介绍一下二叉树遍历的知识。 &#xff08;我是一个纯小白&#xff09; 一、二…

二叉树的前序,中序,后序遍历

前序遍历&#xff1a;根节点->左子树->右子树&#xff08;根->左->右&#xff09; 中序遍历&#xff1a;左子树->根节点->右子树&#xff08;左->根->右&#xff09; 后序遍历&#xff1a;左子树->右子树->根节点&#xff08;左->右->根&a…

二叉树的前序、中序、后序遍历

文章目录 前言一、用递归法实现遍历1.1 前序遍历1.2 中序遍历1.3 后序遍历 二、用迭代法实现遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.3.1 后序解法一2.3.2 后序解法二 三、测试验证 前言 本文主要记录二叉树的遍历方法&#xff0c;文章的主要知识点来源为&#xff1a; htt…

二叉树中已知前序和中序求其后序(图解加技巧让你轻松掌握)

一 首先咱得了解二叉树的结构&#xff0c;和前序/中序/后序遍历分别是什么。 1&#xff1a;什么是根和左右孩子&#xff1a;二叉树的每个节点都可以作为根&#xff0c;每个根下面的叫左右孩子&#xff0c;也可以没有孩子 ​ 实际使用中会如下图A是根左孩子是B,右孩子是C&a…

二叉树的前序、中序、后序

一、概念 二叉树遍历分为三种&#xff1a;前序、中序、后序&#xff0c;其中序遍历最为重要。 二、特点 A&#xff1a;根节点、B&#xff1a;左节点、C&#xff1a;右节点; 前序顺序是ABC&#xff08;根节点排最先&#xff0c;然后同级先左后右&#xff09;&#xff1b;中序…

数据结构:二叉树(先、中、后序)

一、实现功能描述&#xff1a; 1、使用先序序列来创建二叉树&#xff0c;并使用递归算法实现先序、中序、后序输出。 2、使用先序序列来创建二叉树&#xff0c;并使用非递归算法实现先序、中序、后序输出。 3、使用中序、后序的序列来创建二叉树&#xff0c;并使用先序输出。 …

二叉树的先序、中序、后序遍历超详解

以上图为基础 ①前序遍历的方式是&#xff1a;首先访问根节点&#xff0c;然后访问左子树&#xff0c;最后访问右子树。 前序遍历序列&#xff1a;F C A D B E H G M ②中序遍历的方式是&#xff1a;首先访问左子树&#xff0c;接着访问根结点&#xff0c;最后访问右子树。 中序…

二叉树的先序、中序、后序以及层次遍历

二叉树的先序、中序、后序以及层次遍历 方法&#xff1a;在遍历二叉树的时候&#xff0c;一个节点的遍历我们把它看做要经过它三次(下图红色区域)。 当经过一次&#xff0c;被写出来的点&#xff0c;我们称它为先序遍历。 当经过两次&#xff0c;被写出来的点&#xff0c;我…

二叉树的遍历(先序、中序、后序和层次法)

一、二叉树的遍历 ●遍历是指按指定的规律从根结点开始&#xff0c;对二叉树中的每个结点遍历一次且仅遍历一次。 ●遍历可以采用递归方法&#xff08;程序简单&#xff09;和非递归方法&#xff08;程序稍复杂&#xff09;。从中可以寻出“足迹”。 例如下列一颗简单的二叉树…

原生ajax的实现步骤

原生ajax的实现步骤 创建ajax对象 var xhr new XMLHttpRequest(); 告诉ajax请求地址以及请求方式&#xff08;ajax下的open方法&#xff09; xhr.open(‘get’,’http://www.example.com’); 第一个参数为请求方式&#xff0c;第二个参数为请求地址/服务器端对应的路由请求地…

2、原生AJAX

目录 1、GET请求 (1)ajax (2)js路由 2、POST请求 &#xff08;1&#xff09;ajax &#xff08;2&#xff09;js路由 3、服务端响应JOSN数据 &#xff08;1&#xff09;ajax &#xff08;2&#xff09;js路由 4、IE缓存问题 &#xff08;1&#xff09;ajax &#xf…

AJAX ------ 原生 AJAX

原生 AJAX GET 请求 一. 实例要求&#xff1a;点击按钮&#xff0c;发送GET请求&#xff0c;在 div 中做呈现 HELLO AJAX 创建 server.js 文件 //1.引入expressconst express require(express);//2.创建应用对象const app express();//3.创建路由规则//requset是对请求报…

关于原生的Ajax详解

一、Ajax对于前端开发的意义 我们常称Ajax是前端开发者的梦想&#xff0c;为什么这么说呢&#xff1f;Ajax的出现揭开了无刷更新页面数据的时代&#xff0c;JavaScript的实用性也得到了巨大的提升&#xff0c;网页可以在不重载的情况下&#xff0c;实现异步更新&#xff0c;而在…

猿创征文 | 如何使用原生AJAX请求数据

目录 一、什么是AJAX 二、AJAX请求数据的步骤 第一步&#xff1a;创建XMLHttpRequest的实例对象 第二步&#xff1a;打开一个连接 open() 第三步&#xff1a;设置请求头 setRequestHeader() 第四步&#xff1a;发送请求 send() 第五步&#xff1a;接收响应 三、常用请求…

原生ajax和Jquery的ajax

目录 原生ajax 传统请求&#xff08;同步方式&#xff09;的问题 Ajax优势和作用 Ajax请求与传统请求的区别&#xff1a; ajax原理&#xff08;方法&#xff0c;属性 &#xff09; XMLHttpRequest open send 属性 readyState tatus responseText 事件 ajax实现步骤…