HDU 1710 & WUSTOJ 1649 求后序遍历 【二叉树】

题目来源于 http://acm.wust.edu.cn/problem.php?id=1649&soj=0
在这里插入图片描述
★这题没有应用到二叉树,但是解出这题要对二叉树的遍历方式有深刻的理解qwq

相关知识:

1.二叉树前序遍历: 先访问根节点,再遍历左子树,最后遍历右子树。简单地说就是,先中再左后右
2.二叉树中序遍历: 先遍历根节点的左子树,再遍历根节点,最后遍历根节点的右子树。先左再中后右
3.二叉树后序遍历: 先遍历根节点的左子树,再遍历根节点的右子树,最后遍历根节点。先左再右后中
4.二叉树层序遍历: 先遍历最上面一层,逐渐往下遍历,层层从左到右一次遍历。从上到下,从左往右
以下图为例,图来自HDU 1710 http://acm.hdu.edu.cn/showproblem.php?pid=1710
在这里插入图片描述
前序遍历:1 2 4 7 3 5 8 9 6
中序遍历:4 7 2 1 8 5 9 3 6
后序遍历:7 4 2 8 9 5 6 3 1
层序遍历:1 2 3 4 5 6 7 8 9

思路:

我们已知前序和中序遍历,问题是怎么反推出后序遍历。就要抓住他们遍历的特点。还是以上图为例~
前序遍历的第一个一定是根节点,它在中序遍历中的位置将左右子树完美分隔开来4 7 2是左,8 5 8 3 6是右
再分别以这两个小的二叉树重复此操作。
我是通过递归输出的,详见代码~

注意:

这两题都是求后序遍历,但是一个是数字形式一个是字母形式,所以操作起来会有一点小区别的。
因为数字要有一个空格隔开,字母没有。在HDU上面多有一个标记变量

代码:

WUSTOJ 代码如下

#include<bits/stdc++.h>
using namespace std;
char s1[105],s2[105];
void hhh(int a,int b,int n)
{
    if(n==1) {cout<<s1[a]; return ;}
    else if(n==0) return ;
    int i;
    for(i=0;s1[a]!=s2[b+i];i++);
    hhh(a+1,b,i);
    hhh(a+i+1,b+i+1,n-i-1);
    cout<<s1[a];
}
int main()
{
    while(cin>>s1>>s2){
        int len=strlen(s1);
        hhh(0,0,len);
        cout<<endl;
    }
}

HDU代码如下,注意多了一个flag标记变量

#include<stdio.h>
using namespace std;
int t1[1005],t2[1005];
void hhh(int a,int b,int n,int flag)
{
    if(n==1) {printf("%d ",t1[a]); return ;}
    else if(!n) return ;
    int i;
    for(i=0;t1[a]!=t2[b+i];i++);
    hhh(a+1,b,i,0);
    hhh(a+i+1,b+i+1,n-i-1,0);
    if(flag) printf("%d",t1[a]);
    else printf("%d ",t1[a]);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int i;
        for(i=1;i<=n;i++) scanf("%d",&t1[i]);
        for(i=1;i<=n;i++) scanf("%d",&t2[i]);
        hhh(1,1,n,1);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43890662/article/details/87268739