(数据结构)如何根据树的后序中序遍历求树的前序遍历

后序+中序->前序

思路借鉴于伟大的柳婼小姐姐~

  由于树的后序遍历顺序是:左 右 根

    树的中序遍历顺序是:左 根 右

  所以后序遍历中每一段的最后位置节点就是该子树的根节点。比如对于后序遍历 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 }

 

posted @ 2019-09-22 20:54  *starry*  阅读(855)  评论(0编辑  收藏  举报