已知前序遍列和中序遍历求后序遍历

本文介绍了一种根据给定的二叉树前序和中序遍历序列,通过递归算法来计算并输出该二叉树的后序遍历序列的方法。此算法适用于不超过26个结点的大写字母标记的二叉树。

 

题目描述

二叉树的前序、中序、后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树; 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树; 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。

输入描述:

两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。

输出描述:

输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。

示例1

输入

ABC
BAC
FDXEAG
XDEFAG

输出

BCA
XEDGAF

 

#include <stdio.h>
#include <string.h>
void transfer(char *per,char *mid,int len){
    if(len==0) return ;
    char *p=per,*q=mid;
    int left_len=0;
    while(*(q++)!=(*p))
        left_len++;
    transfer(p+1,mid,left_len);
    transfer(p+left_len+1,q,len-left_len-1);
    printf("%c",*p);
}
int main(){
    char per[50],mid[50];
    while(~scanf("%s%s",per,mid)){
        transfer(per,mid,strlen(per));
        printf("\n");
    }
    return 0;
}

 

虽然给定引用中未直接给出PTA平台上根据前序遍历序遍历后序遍历的具体解答,但可以从引用中获取一些思路。 已知序遍历是先访问左子树,然后访问根节点,最后遍历右子树 (left→root→right) ,而前序遍历是先访问根节点,然后遍历左子树,最后遍历右子树 (root→left→right) [^1]。 后序遍历(left→right→root)可以采用如下思路: - 前序遍历的第一个元素是根节点。 - 在中序遍历中找到该根节点的位置,根节点左边的元素构成左子树的中序遍历,右边的元素构成右子树的中序遍历。 - 根据左子树右子树中序遍历的长度,可以从前序遍历中划分出左子树右子树的前序遍历。 - 递归地对左子树右子树进行上述操作,最终得到后序遍历结果。 以下给出一个简单的代码示例(采用将数组传参的方法): ```cpp #include <iostream> #include <vector> using namespace std; // 根据前序中序后序 void postorder(vector<int>& pre, vector<int>& in, int preStart, int preEnd, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) return; // 前序遍历的第一个元素是根节点 int root = pre[preStart]; // 在中序遍历中找到根节点的位置 int rootIndexInorder = inStart; while (in[rootIndexInorder] != root) { rootIndexInorder++; } // 计算左子树的节点数量 int leftSubtreeSize = rootIndexInorder - inStart; // 递归处理左子树 postorder(pre, in, preStart + 1, preStart + leftSubtreeSize, inStart, rootIndexInorder - 1); // 递归处理右子树 postorder(pre, in, preStart + leftSubtreeSize + 1, preEnd, rootIndexInorder + 1, inEnd); // 输出根节点(后序遍历最后输出根节点) cout << root; if (preStart != 0) cout << " "; } int main() { int n; cin >> n; vector<int> pre(n), in(n); for (int i = 0; i < n; i++) { cin >> pre[i]; } for (int i = 0; i < n; i++) { cin >> in[i]; } postorder(pre, in, 0, n - 1, 0, n - 1); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值