(数据结构)如何根据树的后序中序遍历求树的前序遍历
后序+中序->前序
思路借鉴于伟大的柳婼小姐姐~
由于树的后序遍历顺序是:左 右 根
树的中序遍历顺序是:左 根 右
所以后序遍历中每一段的最后位置节点就是该子树的根节点。比如对于后序遍历 3 4 2 6 5 1,1是该树的根节点。然后我们从中序遍历中找到1的位置,那么1的左边即为树的左子树,右边为右子树。由此可以知道左子树和右子树各有多少个节点。因为不论什么顺序的遍历,同一边的子树节点不会分开,所以如果中序遍历为3 2 4 1 6 5,3 2 4为左子树,长度为3,所以在后序遍历中前三位一定是左子树,2是3 4 2的最后位,所以2是左子树的根节点,以此类推。
可以写递归函数求先序遍历。dfs(root,st,ed);其中root为后序遍历中的根节点位置,st和ed是以root为根节点的子树在中序遍历中的位置。因为后序的最后一个总是根结点,令i在中序中找到该根结点,则i把中序分为两部分,左边是左子树,右边是右子树。因为是输出先序(根左右),所以先打印出当前根结点,然后打印左子树,再打印右子树。左子树在后序中的根结点为root – (end – i + 1),即为当前根结点-右子树的个数。左子树在中序中的起始点start为start,末尾end点为i – 1.右子树的根结点为当前根结点的前一个结点root – 1,右子树的起始点start为i+1,末尾end点为end。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5 int post[20],in[20];
6 //root是后序中的当前根的位置,st,ed是该子树在中序遍历中的最左位置和最右位置
7 void dfs(int root,int st,int ed)
8 {
9 if(st>ed)
10 return;
11 int i=st;
12 while(in[i]!=post[root])
13 i++;
14 cout<<post[root]<<" ";
15 dfs(root-(ed-i+1),st,i-1);
16 dfs(root-1,i+1,ed);
17 }
18 int main()
19 {
20 int n;
21 cin>>n;
22 for(int i=0;i<n;i++)
23 cin>>post[i];
24 for(int i=0;i<n;i++)
25 cin>>in[i];
26 dfs(n-1,0,n-1);
27 return 0;
28 }